From 33637cfd00eb5d15eb5a2234ee4fbf665e17ae5d Mon Sep 17 00:00:00 2001 From: Solutionsdesign Date: Sun, 7 Nov 2010 19:20:15 +0100 Subject: [PATCH] First commit for LLBLGen Pro v2.6 version of HnD, pulled from svn --- BL/AssemblyInfo.cs | 77 + BL/ForumGuiHelper.cs | 353 ++ BL/ForumManager.cs | 247 ++ BL/Globals.cs | 167 + BL/GuiHelper.cs | 73 + BL/LICENSE.txt | 280 ++ BL/MessageGuiHelper.cs | 314 ++ BL/MessageManager.cs | 333 ++ BL/SD.HnD.BL.csproj | 210 ++ BL/Searcher.cs | 321 ++ BL/SectionGuiHelper.cs | 117 + BL/SectionManager.cs | 118 + BL/SecurityGuiHelper.cs | 370 ++ BL/SecurityManager.cs | 609 ++++ BL/SupportQueueGuiHelper.cs | 235 ++ BL/SupportQueueManager.cs | 243 ++ BL/SystemGuiHelper.cs | 47 + BL/SystemManager.cs | 67 + BL/ThreadGuiHelper.cs | 507 +++ BL/ThreadManager.cs | 548 +++ BL/UserGuiHelper.cs | 469 +++ BL/UserManager.cs | 519 +++ DAL/App.config | 6 + DAL/AssemblyInfo.cs | 77 + .../MessagesInThreadTypedListExtension.cs | 115 + .../ActionRightCollection.cs | 258 ++ DAL/CollectionClasses/AttachmentCollection.cs | 270 ++ .../AuditActionCollection.cs | 258 ++ .../AuditDataCoreCollection.cs | 293 ++ .../AuditDataMessageRelatedCollection.cs | 300 ++ .../AuditDataThreadRelatedCollection.cs | 300 ++ DAL/CollectionClasses/BookmarkCollection.cs | 277 ++ DAL/CollectionClasses/ForumCollection.cs | 341 ++ .../ForumRoleForumActionRightCollection.cs | 284 ++ DAL/CollectionClasses/IPBanCollection.cs | 270 ++ DAL/CollectionClasses/MessageCollection.cs | 277 ++ .../RoleAuditActionCollection.cs | 277 ++ DAL/CollectionClasses/RoleCollection.cs | 388 +++ .../RoleSystemActionRightCollection.cs | 277 ++ DAL/CollectionClasses/RoleUserCollection.cs | 277 ++ DAL/CollectionClasses/SectionCollection.cs | 194 ++ .../SupportQueueCollection.cs | 194 ++ .../SupportQueueThreadCollection.cs | 284 ++ DAL/CollectionClasses/SystemDataCollection.cs | 277 ++ DAL/CollectionClasses/ThreadCollection.cs | 471 +++ .../ThreadSubscriptionCollection.cs | 277 ++ DAL/CollectionClasses/UserCollection.cs | 594 ++++ DAL/CollectionClasses/UserTitleCollection.cs | 194 ++ DAL/ConstantsEnums.cs | 680 ++++ DAL/DaoClasses/ActionRightDAO.cs | 153 + DAL/DaoClasses/AttachmentDAO.cs | 177 + DAL/DaoClasses/AuditActionDAO.cs | 153 + DAL/DaoClasses/AuditDataCoreDAO.cs | 185 + DAL/DaoClasses/AuditDataMessageRelatedDAO.cs | 174 + DAL/DaoClasses/AuditDataThreadRelatedDAO.cs | 174 + DAL/DaoClasses/BookmarkDAO.cs | 185 + DAL/DaoClasses/ForumDAO.cs | 235 ++ .../ForumRoleForumActionRightDAO.cs | 193 ++ DAL/DaoClasses/IPBanDAO.cs | 177 + DAL/DaoClasses/MessageDAO.cs | 185 + DAL/DaoClasses/RoleAuditActionDAO.cs | 185 + DAL/DaoClasses/RoleDAO.cs | 251 ++ DAL/DaoClasses/RoleSystemActionRightDAO.cs | 185 + DAL/DaoClasses/RoleUserDAO.cs | 185 + DAL/DaoClasses/SectionDAO.cs | 103 + DAL/DaoClasses/SupportQueueDAO.cs | 103 + DAL/DaoClasses/SupportQueueThreadDAO.cs | 212 ++ DAL/DaoClasses/SystemDataDAO.cs | 185 + DAL/DaoClasses/ThreadDAO.cs | 333 ++ DAL/DaoClasses/ThreadSubscriptionDAO.cs | 185 + DAL/DaoClasses/TypedListDAO.cs | 75 + DAL/DaoClasses/UserDAO.cs | 442 +++ DAL/DaoClasses/UserTitleDAO.cs | 103 + .../ActionRightEntityBase.cs | 1061 ++++++ DAL/EntityBaseClasses/AttachmentEntityBase.cs | 924 +++++ .../AuditActionEntityBase.cs | 1035 ++++++ .../AuditDataCoreEntityBase.cs | 1165 +++++++ .../AuditDataMessageRelatedEntityBase.cs | 847 +++++ .../AuditDataThreadRelatedEntityBase.cs | 847 +++++ DAL/EntityBaseClasses/BookmarkEntityBase.cs | 1089 ++++++ DAL/EntityBaseClasses/ForumEntityBase.cs | 1602 +++++++++ .../ForumRoleForumActionRightEntityBase.cs | 1332 ++++++++ DAL/EntityBaseClasses/IPBanEntityBase.cs | 970 ++++++ DAL/EntityBaseClasses/MessageEntityBase.cs | 1441 ++++++++ .../RoleAuditActionEntityBase.cs | 1089 ++++++ DAL/EntityBaseClasses/RoleEntityBase.cs | 1849 ++++++++++ .../RoleSystemActionRightEntityBase.cs | 1089 ++++++ DAL/EntityBaseClasses/RoleUserEntityBase.cs | 1089 ++++++ DAL/EntityBaseClasses/SectionEntityBase.cs | 809 +++++ .../SupportQueueEntityBase.cs | 952 ++++++ .../SupportQueueThreadEntityBase.cs | 1611 +++++++++ DAL/EntityBaseClasses/SystemDataEntityBase.cs | 1170 +++++++ DAL/EntityBaseClasses/ThreadEntityBase.cs | 2282 +++++++++++++ .../ThreadSubscriptionEntityBase.cs | 1089 ++++++ DAL/EntityBaseClasses/UserEntityBase.cs | 3012 +++++++++++++++++ DAL/EntityBaseClasses/UserTitleEntityBase.cs | 783 +++++ DAL/EntityClasses/ActionRightEntity.cs | 102 + DAL/EntityClasses/AttachmentEntity.cs | 102 + DAL/EntityClasses/AuditActionEntity.cs | 102 + DAL/EntityClasses/AuditDataCoreEntity.cs | 102 + .../AuditDataMessageRelatedEntity.cs | 102 + .../AuditDataThreadRelatedEntity.cs | 102 + DAL/EntityClasses/BookmarkEntity.cs | 105 + DAL/EntityClasses/CommonEntityBase.cs | 66 + DAL/EntityClasses/ForumEntity.cs | 102 + .../ForumRoleForumActionRightEntity.cs | 108 + DAL/EntityClasses/IPBanEntity.cs | 102 + DAL/EntityClasses/MessageEntity.cs | 102 + DAL/EntityClasses/RoleAuditActionEntity.cs | 105 + DAL/EntityClasses/RoleEntity.cs | 102 + .../RoleSystemActionRightEntity.cs | 105 + DAL/EntityClasses/RoleUserEntity.cs | 105 + DAL/EntityClasses/SectionEntity.cs | 102 + DAL/EntityClasses/SupportQueueEntity.cs | 102 + DAL/EntityClasses/SupportQueueThreadEntity.cs | 105 + DAL/EntityClasses/SystemDataEntity.cs | 102 + DAL/EntityClasses/ThreadEntity.cs | 102 + DAL/EntityClasses/ThreadSubscriptionEntity.cs | 105 + DAL/EntityClasses/UserEntity.cs | 102 + DAL/EntityClasses/UserTitleEntity.cs | 102 + DAL/FactoryClasses/DaoFactory.cs | 203 ++ DAL/FactoryClasses/EntityFactories.cs | 1169 +++++++ DAL/FactoryClasses/EntityFieldFactory.cs | 250 ++ DAL/FactoryClasses/EntityFieldsFactory.cs | 132 + DAL/HelperClasses/DbUtils.cs | 305 ++ DAL/HelperClasses/DbUtilsComPlus.cs | 123 + DAL/HelperClasses/FieldCreationClasses.cs | 783 +++++ DAL/HelperClasses/FieldInfoProvider.cs | 307 ++ DAL/HelperClasses/InheritanceInfoProvider.cs | 86 + DAL/HelperClasses/PersistenceInfoProvider.cs | 325 ++ DAL/HelperClasses/ResultsetFields.cs | 62 + DAL/HelperClasses/Transaction.cs | 83 + DAL/HelperClasses/TransactionComPlus.cs | 77 + DAL/HelperClasses/TypeDefaultValue.cs | 112 + DAL/LICENSE.txt | 0 DAL/RelationClasses/ActionRightRelations.cs | 85 + DAL/RelationClasses/AttachmentRelations.cs | 69 + DAL/RelationClasses/AuditActionRelations.cs | 85 + DAL/RelationClasses/AuditDataCoreRelations.cs | 137 + .../AuditDataMessageRelatedRelations.cs | 125 + .../AuditDataThreadRelatedRelations.cs | 125 + DAL/RelationClasses/BookmarkRelations.cs | 84 + DAL/RelationClasses/DynamicRelation.cs | 78 + DAL/RelationClasses/ForumRelations.cs | 114 + .../ForumRoleForumActionRightRelations.cs | 99 + DAL/RelationClasses/IPBanRelations.cs | 69 + DAL/RelationClasses/MessageRelations.cs | 114 + .../RoleAuditActionRelations.cs | 84 + DAL/RelationClasses/RoleRelations.cs | 149 + .../RoleSystemActionRightRelations.cs | 84 + DAL/RelationClasses/RoleUserRelations.cs | 84 + DAL/RelationClasses/SectionRelations.cs | 69 + DAL/RelationClasses/SupportQueueRelations.cs | 85 + .../SupportQueueThreadRelations.cs | 117 + DAL/RelationClasses/SystemDataRelations.cs | 84 + DAL/RelationClasses/ThreadRelations.cs | 164 + .../ThreadSubscriptionRelations.cs | 84 + DAL/RelationClasses/UserRelations.cs | 211 ++ DAL/RelationClasses/UserTitleRelations.cs | 69 + DAL/SD.HnD.DAL.csproj | 569 ++++ .../ActionProcedures.cs | 38 + .../RetrievalProcedures.cs | 38 + .../ForumMessagesTypedList.cs | 975 ++++++ .../ForumsWithSectionNameTypedList.cs | 811 +++++ .../MessagesInThreadTypedList.cs | 1190 +++++++ DAL/TypedListClasses/SearchResultTypedList.cs | 759 +++++ Docs/HnD Administration Guide.doc | Bin 0 -> 67072 bytes Docs/HnD Developer Guide.doc | Bin 0 -> 53760 bytes Docs/HnD Installation Guide.doc | Bin 0 -> 220160 bytes GUI/ActiveThreads.aspx | 115 + GUI/ActiveThreads.aspx.cs | 141 + GUI/Admin/AddForum.aspx | 191 ++ GUI/Admin/AddForum.aspx.cs | 132 + GUI/Admin/AddRole.aspx | 87 + GUI/Admin/AddRole.aspx.cs | 109 + GUI/Admin/AddSection.aspx | 109 + GUI/Admin/AddSection.aspx.cs | 101 + GUI/Admin/AddUsersToRole.aspx | 54 + GUI/Admin/AddUsersToRole.aspx.cs | 145 + GUI/Admin/AdminMaster.master | 21 + GUI/Admin/AdminMaster.master.cs | 46 + GUI/Admin/BanUnBanUser.aspx | 46 + GUI/Admin/BanUnBanUser.aspx.cs | 123 + GUI/Admin/Default.aspx | 184 + GUI/Admin/Default.aspx.cs | 87 + GUI/Admin/DeleteForum.aspx | 61 + GUI/Admin/DeleteForum.aspx.cs | 135 + GUI/Admin/DeleteRole.aspx | 64 + GUI/Admin/DeleteRole.aspx.cs | 113 + GUI/Admin/DeleteSection.aspx | 66 + GUI/Admin/DeleteSection.aspx.cs | 138 + GUI/Admin/DeleteUser.aspx | 41 + GUI/Admin/DeleteUser.aspx.cs | 113 + GUI/Admin/FindUser.ascx | 58 + GUI/Admin/FindUser.ascx.cs | 227 ++ GUI/Admin/Header.ascx | 22 + GUI/Admin/Header.ascx.cs | 50 + GUI/Admin/ManageAuditActionsPerRole.aspx | 68 + GUI/Admin/ManageAuditActionsPerRole.aspx.cs | 167 + GUI/Admin/ManageForumRights.aspx | 78 + GUI/Admin/ManageForumRights.aspx.cs | 225 ++ GUI/Admin/ManageIPBans.aspx | 165 + GUI/Admin/ManageIPBans.aspx.cs | 134 + GUI/Admin/ManageRoleForumRights.aspx | 61 + GUI/Admin/ManageRoleForumRights.aspx.cs | 107 + GUI/Admin/ManageSupportQueues.aspx | 136 + GUI/Admin/ManageSupportQueues.aspx.cs | 129 + GUI/Admin/ManageUsersInRole.aspx | 71 + GUI/Admin/ManageUsersInRole.aspx.cs | 113 + GUI/Admin/ModifyDeleteForum.aspx | 80 + GUI/Admin/ModifyDeleteForum.aspx.cs | 111 + GUI/Admin/ModifyDeleteRole.aspx | 80 + GUI/Admin/ModifyDeleteRole.aspx.cs | 111 + GUI/Admin/ModifyDeleteSection.aspx | 76 + GUI/Admin/ModifyDeleteSection.aspx.cs | 113 + GUI/Admin/ModifyForum.aspx | 137 + GUI/Admin/ModifyForum.aspx.cs | 177 + GUI/Admin/ModifyRole.aspx | 71 + GUI/Admin/ModifyRole.aspx.cs | 153 + GUI/Admin/ModifySection.aspx | 74 + GUI/Admin/ModifySection.aspx.cs | 127 + GUI/Admin/ModifySystemParameters.aspx | 103 + GUI/Admin/ModifySystemParameters.aspx.cs | 174 + GUI/Admin/ModifyUserProfile.aspx | 147 + GUI/Admin/ModifyUserProfile.aspx.cs | 210 ++ GUI/Admin/RemoveUsersFromRole.aspx | 53 + GUI/Admin/RemoveUsersFromRole.aspx.cs | 152 + GUI/Admin/Reparser.aspx | 46 + GUI/Admin/Reparser.aspx.cs | 102 + GUI/Admin/SendEmail.aspx | 93 + GUI/Admin/SendEmail.aspx.cs | 191 ++ GUI/Admin/ViewAuditInfo.aspx | 64 + GUI/Admin/ViewAuditInfo.aspx.cs | 154 + GUI/App_Code/ApplicationAdapter.cs | 426 +++ GUI/App_Code/CacheManager.cs | 245 ++ GUI/App_Code/SessionAdapter.cs | 585 ++++ GUI/App_Data/CollapseExpandScript.template | 140 + GUI/App_Data/Noise.txt | 124 + GUI/App_Data/RegistrationReplyMail.template | 17 + .../ThreadUpdatedNotification.template | 12 + GUI/App_Data/ubb_message.xsl | 191 ++ GUI/App_Data/ubb_signature.xsl | 100 + GUI/App_Themes/BlueAndGrey/main.css | 558 +++ GUI/App_Themes/BlueAndGrey/main.skin | 113 + GUI/App_Themes/BlueAndGrey/pics/HnDLogo.jpg | Bin 0 -> 22150 bytes .../pics/background_explanationbox.gif | Bin 0 -> 14146 bytes .../pics/background_header_bottom.jpg | Bin 0 -> 1841 bytes .../pics/background_header_top.jpg | Bin 0 -> 5733 bytes .../BlueAndGrey/pics/background_page.jpg | Bin 0 -> 13695 bytes .../pics/background_supportarea_1line.gif | Bin 0 -> 1802 bytes .../pics/background_tablehd_1line.jpg | Bin 0 -> 774 bytes .../pics/background_tablehd_2line.jpg | Bin 0 -> 1888 bytes .../BlueAndGrey/pics/button_bookmark.gif | Bin 0 -> 1251 bytes .../BlueAndGrey/pics/button_close.gif | Bin 0 -> 1206 bytes .../BlueAndGrey/pics/button_collapse.gif | Bin 0 -> 388 bytes .../BlueAndGrey/pics/button_delete.gif | Bin 0 -> 1116 bytes .../BlueAndGrey/pics/button_done.gif | Bin 0 -> 999 bytes .../BlueAndGrey/pics/button_done_small.gif | Bin 0 -> 873 bytes .../BlueAndGrey/pics/button_expand.gif | Bin 0 -> 389 bytes .../BlueAndGrey/pics/button_move.gif | Bin 0 -> 699 bytes .../BlueAndGrey/pics/button_notdone.gif | Bin 0 -> 899 bytes .../BlueAndGrey/pics/button_notdone_small.gif | Bin 0 -> 852 bytes .../BlueAndGrey/pics/button_print.gif | Bin 0 -> 1156 bytes .../BlueAndGrey/pics/button_properties.gif | Bin 0 -> 1146 bytes .../BlueAndGrey/pics/button_rss.gif | Bin 0 -> 560 bytes .../pics/button_subscribetothread.gif | Bin 0 -> 1288 bytes .../BlueAndGrey/pics/button_unbookmark.gif | Bin 0 -> 1348 bytes .../pics/button_unsubscribefromthread.gif | Bin 0 -> 1374 bytes .../BlueAndGrey/pics/icon_newposts.jpg | Bin 0 -> 1109 bytes .../BlueAndGrey/pics/icon_newposts_alt.jpg | Bin 0 -> 1096 bytes .../pics/icon_newposts_legenda.jpg | Bin 0 -> 1088 bytes .../BlueAndGrey/pics/icon_newposts_locked.jpg | Bin 0 -> 1147 bytes .../pics/icon_newposts_locked_alt.jpg | Bin 0 -> 1141 bytes .../pics/icon_newposts_locked_legenda.jpg | Bin 0 -> 1140 bytes .../BlueAndGrey/pics/icon_newposts_sticky.jpg | Bin 0 -> 1159 bytes .../pics/icon_newposts_sticky_alt.jpg | Bin 0 -> 1150 bytes .../pics/icon_newposts_sticky_legenda.jpg | Bin 0 -> 1150 bytes .../BlueAndGrey/pics/icon_nonewposts.jpg | Bin 0 -> 875 bytes .../BlueAndGrey/pics/icon_nonewposts_alt.jpg | Bin 0 -> 856 bytes .../pics/icon_nonewposts_legenda.jpg | Bin 0 -> 939 bytes .../pics/icon_nonewposts_locked.jpg | Bin 0 -> 940 bytes .../pics/icon_nonewposts_locked_alt.jpg | Bin 0 -> 940 bytes .../pics/icon_nonewposts_locked_legenda.jpg | Bin 0 -> 1057 bytes .../pics/icon_nonewposts_sticky.jpg | Bin 0 -> 930 bytes .../pics/icon_nonewposts_sticky_alt.jpg | Bin 0 -> 924 bytes .../pics/icon_nonewposts_sticky_legenda.jpg | Bin 0 -> 1050 bytes GUI/App_Themes/Hnd/main.css | 555 +++ GUI/App_Themes/Hnd/main.skin | 113 + GUI/App_Themes/Hnd/pics/HnDLogo.jpg | Bin 0 -> 18835 bytes .../Hnd/pics/background_explanationbox.gif | Bin 0 -> 11063 bytes .../Hnd/pics/background_header_top.jpg | Bin 0 -> 1011 bytes GUI/App_Themes/Hnd/pics/background_page.gif | Bin 0 -> 25269 bytes .../Hnd/pics/background_supportarea_1line.gif | Bin 0 -> 1943 bytes .../Hnd/pics/background_tablehd_1line.gif | Bin 0 -> 1337 bytes .../Hnd/pics/background_tablehd_2line.gif | Bin 0 -> 2596 bytes GUI/App_Themes/Hnd/pics/button_bookmark.gif | Bin 0 -> 1262 bytes GUI/App_Themes/Hnd/pics/button_close.gif | Bin 0 -> 1214 bytes GUI/App_Themes/Hnd/pics/button_collapse.gif | Bin 0 -> 397 bytes GUI/App_Themes/Hnd/pics/button_delete.gif | Bin 0 -> 1124 bytes GUI/App_Themes/Hnd/pics/button_done.gif | Bin 0 -> 142 bytes GUI/App_Themes/Hnd/pics/button_done_small.gif | Bin 0 -> 872 bytes GUI/App_Themes/Hnd/pics/button_expand.gif | Bin 0 -> 398 bytes GUI/App_Themes/Hnd/pics/button_move.gif | Bin 0 -> 709 bytes GUI/App_Themes/Hnd/pics/button_notdone.gif | Bin 0 -> 103 bytes .../Hnd/pics/button_notdone_small.gif | Bin 0 -> 852 bytes GUI/App_Themes/Hnd/pics/button_print.gif | Bin 0 -> 1164 bytes GUI/App_Themes/Hnd/pics/button_properties.gif | Bin 0 -> 1154 bytes GUI/App_Themes/Hnd/pics/button_rss.gif | Bin 0 -> 565 bytes .../Hnd/pics/button_subscribetothread.gif | Bin 0 -> 1296 bytes GUI/App_Themes/Hnd/pics/button_unbookmark.gif | Bin 0 -> 1406 bytes .../Hnd/pics/button_unsubscribefromthread.gif | Bin 0 -> 1416 bytes GUI/App_Themes/Hnd/pics/icon_newposts.jpg | Bin 0 -> 888 bytes GUI/App_Themes/Hnd/pics/icon_newposts_alt.jpg | Bin 0 -> 871 bytes .../Hnd/pics/icon_newposts_legenda.jpg | Bin 0 -> 889 bytes .../Hnd/pics/icon_newposts_locked.jpg | Bin 0 -> 904 bytes .../Hnd/pics/icon_newposts_locked_alt.jpg | Bin 0 -> 897 bytes .../Hnd/pics/icon_newposts_locked_legenda.jpg | Bin 0 -> 902 bytes .../Hnd/pics/icon_newposts_sticky.jpg | Bin 0 -> 893 bytes .../Hnd/pics/icon_newposts_sticky_alt.jpg | Bin 0 -> 882 bytes .../Hnd/pics/icon_newposts_sticky_legenda.jpg | Bin 0 -> 892 bytes GUI/App_Themes/Hnd/pics/icon_nonewposts.jpg | Bin 0 -> 632 bytes .../Hnd/pics/icon_nonewposts_alt.jpg | Bin 0 -> 671 bytes .../Hnd/pics/icon_nonewposts_legenda.jpg | Bin 0 -> 632 bytes .../Hnd/pics/icon_nonewposts_locked.jpg | Bin 0 -> 646 bytes .../Hnd/pics/icon_nonewposts_locked_alt.jpg | Bin 0 -> 723 bytes .../pics/icon_nonewposts_locked_legenda.jpg | Bin 0 -> 670 bytes .../Hnd/pics/icon_nonewposts_sticky.jpg | Bin 0 -> 663 bytes .../Hnd/pics/icon_nonewposts_sticky_alt.jpg | Bin 0 -> 715 bytes .../pics/icon_nonewposts_sticky_legenda.jpg | Bin 0 -> 670 bytes GUI/App_Themes/LLBLGenPro/main.css | 554 +++ GUI/App_Themes/LLBLGenPro/main.skin | 113 + .../LLBLGenPro/pics/LLBLGenProLogo.jpg | Bin 0 -> 28864 bytes .../pics/background_explanationbox.gif | Bin 0 -> 12207 bytes .../pics/background_header_bottom.jpg | Bin 0 -> 677 bytes .../LLBLGenPro/pics/background_header_top.jpg | Bin 0 -> 1948 bytes .../LLBLGenPro/pics/background_page.gif | Bin 0 -> 18320 bytes .../pics/background_supportarea_1line.gif | Bin 0 -> 1358 bytes .../pics/background_tablehd_1line.jpg | Bin 0 -> 346 bytes .../pics/background_tablehd_2line.jpg | Bin 0 -> 471 bytes .../LLBLGenPro/pics/button_bookmark.gif | Bin 0 -> 1262 bytes .../LLBLGenPro/pics/button_close.gif | Bin 0 -> 1214 bytes .../LLBLGenPro/pics/button_collapse.gif | Bin 0 -> 627 bytes .../LLBLGenPro/pics/button_delete.gif | Bin 0 -> 1124 bytes .../LLBLGenPro/pics/button_done.gif | Bin 0 -> 289 bytes .../LLBLGenPro/pics/button_done_small.gif | Bin 0 -> 872 bytes .../LLBLGenPro/pics/button_expand.gif | Bin 0 -> 624 bytes .../LLBLGenPro/pics/button_move.gif | Bin 0 -> 707 bytes .../LLBLGenPro/pics/button_notdone.gif | Bin 0 -> 103 bytes .../LLBLGenPro/pics/button_notdone_small.gif | Bin 0 -> 852 bytes .../LLBLGenPro/pics/button_print.gif | Bin 0 -> 1164 bytes .../LLBLGenPro/pics/button_properties.gif | Bin 0 -> 1154 bytes GUI/App_Themes/LLBLGenPro/pics/button_rss.gif | Bin 0 -> 560 bytes .../pics/button_subscribetothread.gif | Bin 0 -> 1296 bytes .../LLBLGenPro/pics/button_unbookmark.gif | Bin 0 -> 1279 bytes .../pics/button_unsubscribefromthread.gif | Bin 0 -> 1427 bytes .../LLBLGenPro/pics/icon_newposts.jpg | Bin 0 -> 605 bytes .../LLBLGenPro/pics/icon_newposts_alt.jpg | Bin 0 -> 599 bytes .../LLBLGenPro/pics/icon_newposts_legenda.jpg | Bin 0 -> 600 bytes .../LLBLGenPro/pics/icon_newposts_locked.jpg | Bin 0 -> 621 bytes .../pics/icon_newposts_locked_alt.jpg | Bin 0 -> 621 bytes .../pics/icon_newposts_locked_legenda.jpg | Bin 0 -> 621 bytes .../LLBLGenPro/pics/icon_newposts_sticky.jpg | Bin 0 -> 615 bytes .../pics/icon_newposts_sticky_alt.jpg | Bin 0 -> 611 bytes .../pics/icon_newposts_sticky_legenda.jpg | Bin 0 -> 615 bytes .../LLBLGenPro/pics/icon_nonewposts.jpg | Bin 0 -> 469 bytes .../LLBLGenPro/pics/icon_nonewposts_alt.jpg | Bin 0 -> 463 bytes .../pics/icon_nonewposts_legenda.jpg | Bin 0 -> 468 bytes .../pics/icon_nonewposts_locked.jpg | Bin 0 -> 506 bytes .../pics/icon_nonewposts_locked_alt.jpg | Bin 0 -> 499 bytes .../pics/icon_nonewposts_locked_legenda.jpg | Bin 0 -> 504 bytes .../pics/icon_nonewposts_sticky.jpg | Bin 0 -> 511 bytes .../pics/icon_nonewposts_sticky_alt.jpg | Bin 0 -> 503 bytes .../pics/icon_nonewposts_sticky_legenda.jpg | Bin 0 -> 506 bytes GUI/ApproveAttachments.aspx | 131 + GUI/ApproveAttachments.aspx.cs | 99 + GUI/AssemblyInfo.cs | 80 + GUI/Attachments.aspx | 153 + GUI/Attachments.aspx.cs | 343 ++ GUI/Bookmarks.aspx | 126 + GUI/Bookmarks.aspx.cs | 168 + GUI/CREDITS.txt | 33 + GUI/CloseThread.aspx | 38 + GUI/CloseThread.aspx.cs | 189 ++ GUI/Default.aspx | 222 ++ GUI/Default.aspx.cs | 333 ++ GUI/DeleteMessage.aspx | 82 + GUI/DeleteMessage.aspx.cs | 166 + GUI/DeleteThread.aspx | 70 + GUI/DeleteThread.aspx.cs | 132 + GUI/EditMemoForThread.aspx | 31 + GUI/EditMemoForThread.aspx.cs | 171 + GUI/EditMessage.aspx | 33 + GUI/EditMessage.aspx.cs | 206 ++ GUI/EditProfile.aspx | 160 + GUI/EditProfile.aspx.cs | 180 + GUI/EditProfileSuccessful.aspx | 32 + GUI/EditProfileSuccessful.aspx.cs | 63 + GUI/EditThreadProperties.aspx | 76 + GUI/EditThreadProperties.aspx.cs | 133 + GUI/FileStreamer.aspx | 1 + GUI/FileStreamer.aspx.cs | 107 + GUI/Footer.ascx | 14 + GUI/Footer.ascx.cs | 59 + GUI/Global.asax | 206 ++ GUI/GotoMessage.aspx | 1 + GUI/GotoMessage.aspx.cs | 56 + GUI/Header.ascx | 54 + GUI/Header.ascx.cs | 54 + GUI/HeaderRestrictedMenu.ascx | 24 + GUI/HeaderRestrictedMenu.ascx.cs | 40 + GUI/Help.aspx | 333 ++ GUI/Help.aspx.cs | 64 + GUI/IPBanViewer.aspx | 55 + GUI/IPBanViewer.aspx.cs | 86 + GUI/IgnoredSearchWords.aspx | 39 + GUI/IgnoredSearchWords.aspx.cs | 100 + GUI/LICENSE.txt | 280 ++ GUI/Login.aspx | 75 + GUI/Login.aspx.cs | 105 + GUI/Logout.aspx | 30 + GUI/Logout.aspx.cs | 68 + GUI/MessageEditor.ascx | 292 ++ GUI/MessageEditor.ascx.cs | 406 +++ GUI/Messages.aspx | 319 ++ GUI/Messages.aspx.cs | 538 +++ GUI/MoveThread.aspx | 87 + GUI/MoveThread.aspx.cs | 169 + GUI/MyThreads.aspx | 126 + GUI/MyThreads.aspx.cs | 183 + GUI/MyThreadsPageList.ascx | 9 + GUI/MyThreadsPageList.ascx.cs | 124 + GUI/NewMessage.aspx | 120 + GUI/NewMessage.aspx.cs | 278 ++ GUI/NewThread.aspx | 48 + GUI/NewThread.aspx.cs | 179 + GUI/PageLegend.ascx | 44 + GUI/PageLegend.ascx.cs | 43 + GUI/PageList.ascx | 15 + GUI/PageList.ascx.cs | 228 ++ GUI/PrintMessages.aspx | 85 + GUI/PrintMessages.aspx.cs | 161 + GUI/Profile.aspx | 194 ++ GUI/Profile.aspx.cs | 202 ++ GUI/Register.aspx | 162 + GUI/Register.aspx.cs | 167 + GUI/RegistrationRules.aspx | 68 + GUI/RegistrationRules.aspx.cs | 63 + GUI/RegistrationSuccessful.aspx | 32 + GUI/RegistrationSuccessful.aspx.cs | 64 + GUI/ResetPassword.aspx | 66 + GUI/ResetPassword.aspx.cs | 100 + GUI/ResetPasswordSuccessful.aspx | 30 + GUI/ResetPasswordSuccessful.aspx.cs | 64 + GUI/Rssforum.aspx | 24 + GUI/Rssforum.aspx.cs | 186 + GUI/Search.aspx | 146 + GUI/Search.aspx.cs | 163 + GUI/SearchResultPageList.ascx | 9 + GUI/SearchResultPageList.ascx.cs | 124 + GUI/SearchResults.aspx | 86 + GUI/SearchResults.aspx.cs | 141 + GUI/SearchUnAttended.aspx | 1 + GUI/SearchUnAttended.aspx.cs | 92 + GUI/SupportQueues.aspx | 179 + GUI/SupportQueues.aspx.cs | 205 ++ GUI/Threads.aspx | 143 + GUI/Threads.aspx.cs | 228 ++ GUI/Web.config | 179 + GUI/js/searchhi.js | 247 ++ GUI/pics/attachment.gif | Bin 0 -> 332 bytes GUI/pics/attachmentadd.gif | Bin 0 -> 940 bytes GUI/pics/separator.gif | Bin 0 -> 45 bytes GUI/pics/smileyangry.gif | Bin 0 -> 315 bytes GUI/pics/smileyconfused.gif | Bin 0 -> 314 bytes GUI/pics/smileycool.gif | Bin 0 -> 310 bytes GUI/pics/smileydissapointed.gif | Bin 0 -> 309 bytes GUI/pics/smileyembarrassed.gif | Bin 0 -> 304 bytes GUI/pics/smileylaugh.gif | Bin 0 -> 309 bytes GUI/pics/smileyregular.gif | Bin 0 -> 311 bytes GUI/pics/smileysad.gif | Bin 0 -> 310 bytes GUI/pics/smileyshocked.gif | Bin 0 -> 315 bytes GUI/pics/smileytongue.gif | Bin 0 -> 312 bytes GUI/pics/smileywink.gif | Bin 0 -> 314 bytes HnD.sln | 85 + LICENSE.txt | 280 ++ LLBLGenPro Projects/HnD.lgp | Bin 0 -> 173561 bytes ParserAssemblies/SD.HnD.UBBParser.dll | Bin 0 -> 36864 bytes .../SD.LLBLGen.Pro.DQE.SqlServer.NET20.dll | Bin 0 -> 53248 bytes ...SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll | Bin 0 -> 774144 bytes SQLScripts/FullInstall_HnD.sql | Bin 0 -> 91154 bytes SQLScripts/LICENSE.txt | 280 ++ SQLScripts/Migration_2.0_to_2.1.sql | 412 +++ UBBParser/ParserTester/ExceptionViewer.cs | 292 ++ UBBParser/ParserTester/ExceptionViewer.resx | 120 + UBBParser/ParserTester/LICENSE.txt | 280 ++ UBBParser/ParserTester/MainForm.Designer.cs | 255 ++ UBBParser/ParserTester/MainForm.cs | 139 + UBBParser/ParserTester/MainForm.resx | 120 + UBBParser/ParserTester/Program.cs | 46 + .../ParserTester/Properties/AssemblyInfo.cs | 52 + .../Properties/Resources.Designer.cs | 71 + .../ParserTester/Properties/Resources.resx | 117 + .../Properties/Settings.Designer.cs | 30 + .../ParserTester/Properties/Settings.settings | 7 + UBBParser/ParserTester/Tester.csproj | 94 + UBBParser/UBBParser/AssemblyInfo.cs | 77 + UBBParser/UBBParser/Converter.cs | 46 + UBBParser/UBBParser/EnumsConstants.cs | 159 + UBBParser/UBBParser/Exceptions.cs | 37 + UBBParser/UBBParser/Interfaces.cs | 75 + UBBParser/UBBParser/Interpreter.cs | 810 +++++ UBBParser/UBBParser/LICENSE.txt | 280 ++ UBBParser/UBBParser/LexicalAnalyzer.cs | 76 + UBBParser/UBBParser/NonTerminal.cs | 94 + UBBParser/UBBParser/Parser.cs | 1281 +++++++ UBBParser/UBBParser/Tokenizer.cs | 206 ++ UBBParser/UBBParser/UBBParser.csproj | 199 ++ UBBParser/UBBParser/UBBSyntax.txt | 240 ++ UBBParser/UBBParser/UBBToken.cs | 86 + UBBParser/UBBParser/UBBTokenDefinition.cs | 86 + UBBParser/UBBtoXMLConverter.sln | 26 + Utility/AssemblyInfo.cs | 76 + Utility/GeneralUtils.cs | 199 ++ Utility/HnDGeneralUtils.cs | 199 ++ Utility/LICENSE.txt | 280 ++ Utility/SD.HnD.Utility.csproj | 153 + Utility/TextParser.cs | 178 + 527 files changed, 91451 insertions(+) create mode 100644 BL/AssemblyInfo.cs create mode 100644 BL/ForumGuiHelper.cs create mode 100644 BL/ForumManager.cs create mode 100644 BL/Globals.cs create mode 100644 BL/GuiHelper.cs create mode 100644 BL/LICENSE.txt create mode 100644 BL/MessageGuiHelper.cs create mode 100644 BL/MessageManager.cs create mode 100644 BL/SD.HnD.BL.csproj create mode 100644 BL/Searcher.cs create mode 100644 BL/SectionGuiHelper.cs create mode 100644 BL/SectionManager.cs create mode 100644 BL/SecurityGuiHelper.cs create mode 100644 BL/SecurityManager.cs create mode 100644 BL/SupportQueueGuiHelper.cs create mode 100644 BL/SupportQueueManager.cs create mode 100644 BL/SystemGuiHelper.cs create mode 100644 BL/SystemManager.cs create mode 100644 BL/ThreadGuiHelper.cs create mode 100644 BL/ThreadManager.cs create mode 100644 BL/UserGuiHelper.cs create mode 100644 BL/UserManager.cs create mode 100644 DAL/App.config create mode 100644 DAL/AssemblyInfo.cs create mode 100644 DAL/ClassExtensions/MessagesInThreadTypedListExtension.cs create mode 100644 DAL/CollectionClasses/ActionRightCollection.cs create mode 100644 DAL/CollectionClasses/AttachmentCollection.cs create mode 100644 DAL/CollectionClasses/AuditActionCollection.cs create mode 100644 DAL/CollectionClasses/AuditDataCoreCollection.cs create mode 100644 DAL/CollectionClasses/AuditDataMessageRelatedCollection.cs create mode 100644 DAL/CollectionClasses/AuditDataThreadRelatedCollection.cs create mode 100644 DAL/CollectionClasses/BookmarkCollection.cs create mode 100644 DAL/CollectionClasses/ForumCollection.cs create mode 100644 DAL/CollectionClasses/ForumRoleForumActionRightCollection.cs create mode 100644 DAL/CollectionClasses/IPBanCollection.cs create mode 100644 DAL/CollectionClasses/MessageCollection.cs create mode 100644 DAL/CollectionClasses/RoleAuditActionCollection.cs create mode 100644 DAL/CollectionClasses/RoleCollection.cs create mode 100644 DAL/CollectionClasses/RoleSystemActionRightCollection.cs create mode 100644 DAL/CollectionClasses/RoleUserCollection.cs create mode 100644 DAL/CollectionClasses/SectionCollection.cs create mode 100644 DAL/CollectionClasses/SupportQueueCollection.cs create mode 100644 DAL/CollectionClasses/SupportQueueThreadCollection.cs create mode 100644 DAL/CollectionClasses/SystemDataCollection.cs create mode 100644 DAL/CollectionClasses/ThreadCollection.cs create mode 100644 DAL/CollectionClasses/ThreadSubscriptionCollection.cs create mode 100644 DAL/CollectionClasses/UserCollection.cs create mode 100644 DAL/CollectionClasses/UserTitleCollection.cs create mode 100644 DAL/ConstantsEnums.cs create mode 100644 DAL/DaoClasses/ActionRightDAO.cs create mode 100644 DAL/DaoClasses/AttachmentDAO.cs create mode 100644 DAL/DaoClasses/AuditActionDAO.cs create mode 100644 DAL/DaoClasses/AuditDataCoreDAO.cs create mode 100644 DAL/DaoClasses/AuditDataMessageRelatedDAO.cs create mode 100644 DAL/DaoClasses/AuditDataThreadRelatedDAO.cs create mode 100644 DAL/DaoClasses/BookmarkDAO.cs create mode 100644 DAL/DaoClasses/ForumDAO.cs create mode 100644 DAL/DaoClasses/ForumRoleForumActionRightDAO.cs create mode 100644 DAL/DaoClasses/IPBanDAO.cs create mode 100644 DAL/DaoClasses/MessageDAO.cs create mode 100644 DAL/DaoClasses/RoleAuditActionDAO.cs create mode 100644 DAL/DaoClasses/RoleDAO.cs create mode 100644 DAL/DaoClasses/RoleSystemActionRightDAO.cs create mode 100644 DAL/DaoClasses/RoleUserDAO.cs create mode 100644 DAL/DaoClasses/SectionDAO.cs create mode 100644 DAL/DaoClasses/SupportQueueDAO.cs create mode 100644 DAL/DaoClasses/SupportQueueThreadDAO.cs create mode 100644 DAL/DaoClasses/SystemDataDAO.cs create mode 100644 DAL/DaoClasses/ThreadDAO.cs create mode 100644 DAL/DaoClasses/ThreadSubscriptionDAO.cs create mode 100644 DAL/DaoClasses/TypedListDAO.cs create mode 100644 DAL/DaoClasses/UserDAO.cs create mode 100644 DAL/DaoClasses/UserTitleDAO.cs create mode 100644 DAL/EntityBaseClasses/ActionRightEntityBase.cs create mode 100644 DAL/EntityBaseClasses/AttachmentEntityBase.cs create mode 100644 DAL/EntityBaseClasses/AuditActionEntityBase.cs create mode 100644 DAL/EntityBaseClasses/AuditDataCoreEntityBase.cs create mode 100644 DAL/EntityBaseClasses/AuditDataMessageRelatedEntityBase.cs create mode 100644 DAL/EntityBaseClasses/AuditDataThreadRelatedEntityBase.cs create mode 100644 DAL/EntityBaseClasses/BookmarkEntityBase.cs create mode 100644 DAL/EntityBaseClasses/ForumEntityBase.cs create mode 100644 DAL/EntityBaseClasses/ForumRoleForumActionRightEntityBase.cs create mode 100644 DAL/EntityBaseClasses/IPBanEntityBase.cs create mode 100644 DAL/EntityBaseClasses/MessageEntityBase.cs create mode 100644 DAL/EntityBaseClasses/RoleAuditActionEntityBase.cs create mode 100644 DAL/EntityBaseClasses/RoleEntityBase.cs create mode 100644 DAL/EntityBaseClasses/RoleSystemActionRightEntityBase.cs create mode 100644 DAL/EntityBaseClasses/RoleUserEntityBase.cs create mode 100644 DAL/EntityBaseClasses/SectionEntityBase.cs create mode 100644 DAL/EntityBaseClasses/SupportQueueEntityBase.cs create mode 100644 DAL/EntityBaseClasses/SupportQueueThreadEntityBase.cs create mode 100644 DAL/EntityBaseClasses/SystemDataEntityBase.cs create mode 100644 DAL/EntityBaseClasses/ThreadEntityBase.cs create mode 100644 DAL/EntityBaseClasses/ThreadSubscriptionEntityBase.cs create mode 100644 DAL/EntityBaseClasses/UserEntityBase.cs create mode 100644 DAL/EntityBaseClasses/UserTitleEntityBase.cs create mode 100644 DAL/EntityClasses/ActionRightEntity.cs create mode 100644 DAL/EntityClasses/AttachmentEntity.cs create mode 100644 DAL/EntityClasses/AuditActionEntity.cs create mode 100644 DAL/EntityClasses/AuditDataCoreEntity.cs create mode 100644 DAL/EntityClasses/AuditDataMessageRelatedEntity.cs create mode 100644 DAL/EntityClasses/AuditDataThreadRelatedEntity.cs create mode 100644 DAL/EntityClasses/BookmarkEntity.cs create mode 100644 DAL/EntityClasses/CommonEntityBase.cs create mode 100644 DAL/EntityClasses/ForumEntity.cs create mode 100644 DAL/EntityClasses/ForumRoleForumActionRightEntity.cs create mode 100644 DAL/EntityClasses/IPBanEntity.cs create mode 100644 DAL/EntityClasses/MessageEntity.cs create mode 100644 DAL/EntityClasses/RoleAuditActionEntity.cs create mode 100644 DAL/EntityClasses/RoleEntity.cs create mode 100644 DAL/EntityClasses/RoleSystemActionRightEntity.cs create mode 100644 DAL/EntityClasses/RoleUserEntity.cs create mode 100644 DAL/EntityClasses/SectionEntity.cs create mode 100644 DAL/EntityClasses/SupportQueueEntity.cs create mode 100644 DAL/EntityClasses/SupportQueueThreadEntity.cs create mode 100644 DAL/EntityClasses/SystemDataEntity.cs create mode 100644 DAL/EntityClasses/ThreadEntity.cs create mode 100644 DAL/EntityClasses/ThreadSubscriptionEntity.cs create mode 100644 DAL/EntityClasses/UserEntity.cs create mode 100644 DAL/EntityClasses/UserTitleEntity.cs create mode 100644 DAL/FactoryClasses/DaoFactory.cs create mode 100644 DAL/FactoryClasses/EntityFactories.cs create mode 100644 DAL/FactoryClasses/EntityFieldFactory.cs create mode 100644 DAL/FactoryClasses/EntityFieldsFactory.cs create mode 100644 DAL/HelperClasses/DbUtils.cs create mode 100644 DAL/HelperClasses/DbUtilsComPlus.cs create mode 100644 DAL/HelperClasses/FieldCreationClasses.cs create mode 100644 DAL/HelperClasses/FieldInfoProvider.cs create mode 100644 DAL/HelperClasses/InheritanceInfoProvider.cs create mode 100644 DAL/HelperClasses/PersistenceInfoProvider.cs create mode 100644 DAL/HelperClasses/ResultsetFields.cs create mode 100644 DAL/HelperClasses/Transaction.cs create mode 100644 DAL/HelperClasses/TransactionComPlus.cs create mode 100644 DAL/HelperClasses/TypeDefaultValue.cs create mode 100644 DAL/LICENSE.txt create mode 100644 DAL/RelationClasses/ActionRightRelations.cs create mode 100644 DAL/RelationClasses/AttachmentRelations.cs create mode 100644 DAL/RelationClasses/AuditActionRelations.cs create mode 100644 DAL/RelationClasses/AuditDataCoreRelations.cs create mode 100644 DAL/RelationClasses/AuditDataMessageRelatedRelations.cs create mode 100644 DAL/RelationClasses/AuditDataThreadRelatedRelations.cs create mode 100644 DAL/RelationClasses/BookmarkRelations.cs create mode 100644 DAL/RelationClasses/DynamicRelation.cs create mode 100644 DAL/RelationClasses/ForumRelations.cs create mode 100644 DAL/RelationClasses/ForumRoleForumActionRightRelations.cs create mode 100644 DAL/RelationClasses/IPBanRelations.cs create mode 100644 DAL/RelationClasses/MessageRelations.cs create mode 100644 DAL/RelationClasses/RoleAuditActionRelations.cs create mode 100644 DAL/RelationClasses/RoleRelations.cs create mode 100644 DAL/RelationClasses/RoleSystemActionRightRelations.cs create mode 100644 DAL/RelationClasses/RoleUserRelations.cs create mode 100644 DAL/RelationClasses/SectionRelations.cs create mode 100644 DAL/RelationClasses/SupportQueueRelations.cs create mode 100644 DAL/RelationClasses/SupportQueueThreadRelations.cs create mode 100644 DAL/RelationClasses/SystemDataRelations.cs create mode 100644 DAL/RelationClasses/ThreadRelations.cs create mode 100644 DAL/RelationClasses/ThreadSubscriptionRelations.cs create mode 100644 DAL/RelationClasses/UserRelations.cs create mode 100644 DAL/RelationClasses/UserTitleRelations.cs create mode 100644 DAL/SD.HnD.DAL.csproj create mode 100644 DAL/StoredProcedureCallerClasses/ActionProcedures.cs create mode 100644 DAL/StoredProcedureCallerClasses/RetrievalProcedures.cs create mode 100644 DAL/TypedListClasses/ForumMessagesTypedList.cs create mode 100644 DAL/TypedListClasses/ForumsWithSectionNameTypedList.cs create mode 100644 DAL/TypedListClasses/MessagesInThreadTypedList.cs create mode 100644 DAL/TypedListClasses/SearchResultTypedList.cs create mode 100644 Docs/HnD Administration Guide.doc create mode 100644 Docs/HnD Developer Guide.doc create mode 100644 Docs/HnD Installation Guide.doc create mode 100644 GUI/ActiveThreads.aspx create mode 100644 GUI/ActiveThreads.aspx.cs create mode 100644 GUI/Admin/AddForum.aspx create mode 100644 GUI/Admin/AddForum.aspx.cs create mode 100644 GUI/Admin/AddRole.aspx create mode 100644 GUI/Admin/AddRole.aspx.cs create mode 100644 GUI/Admin/AddSection.aspx create mode 100644 GUI/Admin/AddSection.aspx.cs create mode 100644 GUI/Admin/AddUsersToRole.aspx create mode 100644 GUI/Admin/AddUsersToRole.aspx.cs create mode 100644 GUI/Admin/AdminMaster.master create mode 100644 GUI/Admin/AdminMaster.master.cs create mode 100644 GUI/Admin/BanUnBanUser.aspx create mode 100644 GUI/Admin/BanUnBanUser.aspx.cs create mode 100644 GUI/Admin/Default.aspx create mode 100644 GUI/Admin/Default.aspx.cs create mode 100644 GUI/Admin/DeleteForum.aspx create mode 100644 GUI/Admin/DeleteForum.aspx.cs create mode 100644 GUI/Admin/DeleteRole.aspx create mode 100644 GUI/Admin/DeleteRole.aspx.cs create mode 100644 GUI/Admin/DeleteSection.aspx create mode 100644 GUI/Admin/DeleteSection.aspx.cs create mode 100644 GUI/Admin/DeleteUser.aspx create mode 100644 GUI/Admin/DeleteUser.aspx.cs create mode 100644 GUI/Admin/FindUser.ascx create mode 100644 GUI/Admin/FindUser.ascx.cs create mode 100644 GUI/Admin/Header.ascx create mode 100644 GUI/Admin/Header.ascx.cs create mode 100644 GUI/Admin/ManageAuditActionsPerRole.aspx create mode 100644 GUI/Admin/ManageAuditActionsPerRole.aspx.cs create mode 100644 GUI/Admin/ManageForumRights.aspx create mode 100644 GUI/Admin/ManageForumRights.aspx.cs create mode 100644 GUI/Admin/ManageIPBans.aspx create mode 100644 GUI/Admin/ManageIPBans.aspx.cs create mode 100644 GUI/Admin/ManageRoleForumRights.aspx create mode 100644 GUI/Admin/ManageRoleForumRights.aspx.cs create mode 100644 GUI/Admin/ManageSupportQueues.aspx create mode 100644 GUI/Admin/ManageSupportQueues.aspx.cs create mode 100644 GUI/Admin/ManageUsersInRole.aspx create mode 100644 GUI/Admin/ManageUsersInRole.aspx.cs create mode 100644 GUI/Admin/ModifyDeleteForum.aspx create mode 100644 GUI/Admin/ModifyDeleteForum.aspx.cs create mode 100644 GUI/Admin/ModifyDeleteRole.aspx create mode 100644 GUI/Admin/ModifyDeleteRole.aspx.cs create mode 100644 GUI/Admin/ModifyDeleteSection.aspx create mode 100644 GUI/Admin/ModifyDeleteSection.aspx.cs create mode 100644 GUI/Admin/ModifyForum.aspx create mode 100644 GUI/Admin/ModifyForum.aspx.cs create mode 100644 GUI/Admin/ModifyRole.aspx create mode 100644 GUI/Admin/ModifyRole.aspx.cs create mode 100644 GUI/Admin/ModifySection.aspx create mode 100644 GUI/Admin/ModifySection.aspx.cs create mode 100644 GUI/Admin/ModifySystemParameters.aspx create mode 100644 GUI/Admin/ModifySystemParameters.aspx.cs create mode 100644 GUI/Admin/ModifyUserProfile.aspx create mode 100644 GUI/Admin/ModifyUserProfile.aspx.cs create mode 100644 GUI/Admin/RemoveUsersFromRole.aspx create mode 100644 GUI/Admin/RemoveUsersFromRole.aspx.cs create mode 100644 GUI/Admin/Reparser.aspx create mode 100644 GUI/Admin/Reparser.aspx.cs create mode 100644 GUI/Admin/SendEmail.aspx create mode 100644 GUI/Admin/SendEmail.aspx.cs create mode 100644 GUI/Admin/ViewAuditInfo.aspx create mode 100644 GUI/Admin/ViewAuditInfo.aspx.cs create mode 100644 GUI/App_Code/ApplicationAdapter.cs create mode 100644 GUI/App_Code/CacheManager.cs create mode 100644 GUI/App_Code/SessionAdapter.cs create mode 100644 GUI/App_Data/CollapseExpandScript.template create mode 100644 GUI/App_Data/Noise.txt create mode 100644 GUI/App_Data/RegistrationReplyMail.template create mode 100644 GUI/App_Data/ThreadUpdatedNotification.template create mode 100644 GUI/App_Data/ubb_message.xsl create mode 100644 GUI/App_Data/ubb_signature.xsl create mode 100644 GUI/App_Themes/BlueAndGrey/main.css create mode 100644 GUI/App_Themes/BlueAndGrey/main.skin create mode 100644 GUI/App_Themes/BlueAndGrey/pics/HnDLogo.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/background_explanationbox.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/background_header_bottom.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/background_header_top.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/background_page.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/background_supportarea_1line.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/background_tablehd_1line.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/background_tablehd_2line.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_bookmark.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_close.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_collapse.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_delete.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_done.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_done_small.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_expand.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_move.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_notdone.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_notdone_small.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_print.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_properties.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_rss.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_subscribetothread.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_unbookmark.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/button_unsubscribefromthread.gif create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts_alt.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts_legenda.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts_locked.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts_locked_alt.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts_locked_legenda.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky_alt.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky_legenda.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_alt.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_legenda.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_locked.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_locked_alt.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_locked_legenda.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_sticky.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_sticky_alt.jpg create mode 100644 GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_sticky_legenda.jpg create mode 100644 GUI/App_Themes/Hnd/main.css create mode 100644 GUI/App_Themes/Hnd/main.skin create mode 100644 GUI/App_Themes/Hnd/pics/HnDLogo.jpg create mode 100644 GUI/App_Themes/Hnd/pics/background_explanationbox.gif create mode 100644 GUI/App_Themes/Hnd/pics/background_header_top.jpg create mode 100644 GUI/App_Themes/Hnd/pics/background_page.gif create mode 100644 GUI/App_Themes/Hnd/pics/background_supportarea_1line.gif create mode 100644 GUI/App_Themes/Hnd/pics/background_tablehd_1line.gif create mode 100644 GUI/App_Themes/Hnd/pics/background_tablehd_2line.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_bookmark.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_close.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_collapse.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_delete.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_done.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_done_small.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_expand.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_move.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_notdone.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_notdone_small.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_print.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_properties.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_rss.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_subscribetothread.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_unbookmark.gif create mode 100644 GUI/App_Themes/Hnd/pics/button_unsubscribefromthread.gif create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts_alt.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts_legenda.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts_locked.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts_locked_alt.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts_locked_legenda.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts_sticky.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts_sticky_alt.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_newposts_sticky_legenda.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts_alt.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts_legenda.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts_locked.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts_locked_alt.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts_locked_legenda.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts_sticky.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts_sticky_alt.jpg create mode 100644 GUI/App_Themes/Hnd/pics/icon_nonewposts_sticky_legenda.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/main.css create mode 100644 GUI/App_Themes/LLBLGenPro/main.skin create mode 100644 GUI/App_Themes/LLBLGenPro/pics/LLBLGenProLogo.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/background_explanationbox.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/background_header_bottom.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/background_header_top.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/background_page.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/background_supportarea_1line.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/background_tablehd_1line.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/background_tablehd_2line.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_bookmark.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_close.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_collapse.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_delete.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_done.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_done_small.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_expand.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_move.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_notdone.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_notdone_small.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_print.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_properties.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_rss.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_subscribetothread.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_unbookmark.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/button_unsubscribefromthread.gif create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts_alt.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts_legenda.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts_locked.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts_locked_alt.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts_locked_legenda.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts_sticky.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts_sticky_alt.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_newposts_sticky_legenda.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_alt.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_legenda.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_locked.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_locked_alt.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_locked_legenda.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_sticky.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_sticky_alt.jpg create mode 100644 GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_sticky_legenda.jpg create mode 100644 GUI/ApproveAttachments.aspx create mode 100644 GUI/ApproveAttachments.aspx.cs create mode 100644 GUI/AssemblyInfo.cs create mode 100644 GUI/Attachments.aspx create mode 100644 GUI/Attachments.aspx.cs create mode 100644 GUI/Bookmarks.aspx create mode 100644 GUI/Bookmarks.aspx.cs create mode 100644 GUI/CREDITS.txt create mode 100644 GUI/CloseThread.aspx create mode 100644 GUI/CloseThread.aspx.cs create mode 100644 GUI/Default.aspx create mode 100644 GUI/Default.aspx.cs create mode 100644 GUI/DeleteMessage.aspx create mode 100644 GUI/DeleteMessage.aspx.cs create mode 100644 GUI/DeleteThread.aspx create mode 100644 GUI/DeleteThread.aspx.cs create mode 100644 GUI/EditMemoForThread.aspx create mode 100644 GUI/EditMemoForThread.aspx.cs create mode 100644 GUI/EditMessage.aspx create mode 100644 GUI/EditMessage.aspx.cs create mode 100644 GUI/EditProfile.aspx create mode 100644 GUI/EditProfile.aspx.cs create mode 100644 GUI/EditProfileSuccessful.aspx create mode 100644 GUI/EditProfileSuccessful.aspx.cs create mode 100644 GUI/EditThreadProperties.aspx create mode 100644 GUI/EditThreadProperties.aspx.cs create mode 100644 GUI/FileStreamer.aspx create mode 100644 GUI/FileStreamer.aspx.cs create mode 100644 GUI/Footer.ascx create mode 100644 GUI/Footer.ascx.cs create mode 100644 GUI/Global.asax create mode 100644 GUI/GotoMessage.aspx create mode 100644 GUI/GotoMessage.aspx.cs create mode 100644 GUI/Header.ascx create mode 100644 GUI/Header.ascx.cs create mode 100644 GUI/HeaderRestrictedMenu.ascx create mode 100644 GUI/HeaderRestrictedMenu.ascx.cs create mode 100644 GUI/Help.aspx create mode 100644 GUI/Help.aspx.cs create mode 100644 GUI/IPBanViewer.aspx create mode 100644 GUI/IPBanViewer.aspx.cs create mode 100644 GUI/IgnoredSearchWords.aspx create mode 100644 GUI/IgnoredSearchWords.aspx.cs create mode 100644 GUI/LICENSE.txt create mode 100644 GUI/Login.aspx create mode 100644 GUI/Login.aspx.cs create mode 100644 GUI/Logout.aspx create mode 100644 GUI/Logout.aspx.cs create mode 100644 GUI/MessageEditor.ascx create mode 100644 GUI/MessageEditor.ascx.cs create mode 100644 GUI/Messages.aspx create mode 100644 GUI/Messages.aspx.cs create mode 100644 GUI/MoveThread.aspx create mode 100644 GUI/MoveThread.aspx.cs create mode 100644 GUI/MyThreads.aspx create mode 100644 GUI/MyThreads.aspx.cs create mode 100644 GUI/MyThreadsPageList.ascx create mode 100644 GUI/MyThreadsPageList.ascx.cs create mode 100644 GUI/NewMessage.aspx create mode 100644 GUI/NewMessage.aspx.cs create mode 100644 GUI/NewThread.aspx create mode 100644 GUI/NewThread.aspx.cs create mode 100644 GUI/PageLegend.ascx create mode 100644 GUI/PageLegend.ascx.cs create mode 100644 GUI/PageList.ascx create mode 100644 GUI/PageList.ascx.cs create mode 100644 GUI/PrintMessages.aspx create mode 100644 GUI/PrintMessages.aspx.cs create mode 100644 GUI/Profile.aspx create mode 100644 GUI/Profile.aspx.cs create mode 100644 GUI/Register.aspx create mode 100644 GUI/Register.aspx.cs create mode 100644 GUI/RegistrationRules.aspx create mode 100644 GUI/RegistrationRules.aspx.cs create mode 100644 GUI/RegistrationSuccessful.aspx create mode 100644 GUI/RegistrationSuccessful.aspx.cs create mode 100644 GUI/ResetPassword.aspx create mode 100644 GUI/ResetPassword.aspx.cs create mode 100644 GUI/ResetPasswordSuccessful.aspx create mode 100644 GUI/ResetPasswordSuccessful.aspx.cs create mode 100644 GUI/Rssforum.aspx create mode 100644 GUI/Rssforum.aspx.cs create mode 100644 GUI/Search.aspx create mode 100644 GUI/Search.aspx.cs create mode 100644 GUI/SearchResultPageList.ascx create mode 100644 GUI/SearchResultPageList.ascx.cs create mode 100644 GUI/SearchResults.aspx create mode 100644 GUI/SearchResults.aspx.cs create mode 100644 GUI/SearchUnAttended.aspx create mode 100644 GUI/SearchUnAttended.aspx.cs create mode 100644 GUI/SupportQueues.aspx create mode 100644 GUI/SupportQueues.aspx.cs create mode 100644 GUI/Threads.aspx create mode 100644 GUI/Threads.aspx.cs create mode 100644 GUI/Web.config create mode 100644 GUI/js/searchhi.js create mode 100644 GUI/pics/attachment.gif create mode 100644 GUI/pics/attachmentadd.gif create mode 100644 GUI/pics/separator.gif create mode 100644 GUI/pics/smileyangry.gif create mode 100644 GUI/pics/smileyconfused.gif create mode 100644 GUI/pics/smileycool.gif create mode 100644 GUI/pics/smileydissapointed.gif create mode 100644 GUI/pics/smileyembarrassed.gif create mode 100644 GUI/pics/smileylaugh.gif create mode 100644 GUI/pics/smileyregular.gif create mode 100644 GUI/pics/smileysad.gif create mode 100644 GUI/pics/smileyshocked.gif create mode 100644 GUI/pics/smileytongue.gif create mode 100644 GUI/pics/smileywink.gif create mode 100644 HnD.sln create mode 100644 LICENSE.txt create mode 100644 LLBLGenPro Projects/HnD.lgp create mode 100644 ParserAssemblies/SD.HnD.UBBParser.dll create mode 100644 RuntimeLibraries/SD.LLBLGen.Pro.DQE.SqlServer.NET20.dll create mode 100644 RuntimeLibraries/SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll create mode 100644 SQLScripts/FullInstall_HnD.sql create mode 100644 SQLScripts/LICENSE.txt create mode 100644 SQLScripts/Migration_2.0_to_2.1.sql create mode 100644 UBBParser/ParserTester/ExceptionViewer.cs create mode 100644 UBBParser/ParserTester/ExceptionViewer.resx create mode 100644 UBBParser/ParserTester/LICENSE.txt create mode 100644 UBBParser/ParserTester/MainForm.Designer.cs create mode 100644 UBBParser/ParserTester/MainForm.cs create mode 100644 UBBParser/ParserTester/MainForm.resx create mode 100644 UBBParser/ParserTester/Program.cs create mode 100644 UBBParser/ParserTester/Properties/AssemblyInfo.cs create mode 100644 UBBParser/ParserTester/Properties/Resources.Designer.cs create mode 100644 UBBParser/ParserTester/Properties/Resources.resx create mode 100644 UBBParser/ParserTester/Properties/Settings.Designer.cs create mode 100644 UBBParser/ParserTester/Properties/Settings.settings create mode 100644 UBBParser/ParserTester/Tester.csproj create mode 100644 UBBParser/UBBParser/AssemblyInfo.cs create mode 100644 UBBParser/UBBParser/Converter.cs create mode 100644 UBBParser/UBBParser/EnumsConstants.cs create mode 100644 UBBParser/UBBParser/Exceptions.cs create mode 100644 UBBParser/UBBParser/Interfaces.cs create mode 100644 UBBParser/UBBParser/Interpreter.cs create mode 100644 UBBParser/UBBParser/LICENSE.txt create mode 100644 UBBParser/UBBParser/LexicalAnalyzer.cs create mode 100644 UBBParser/UBBParser/NonTerminal.cs create mode 100644 UBBParser/UBBParser/Parser.cs create mode 100644 UBBParser/UBBParser/Tokenizer.cs create mode 100644 UBBParser/UBBParser/UBBParser.csproj create mode 100644 UBBParser/UBBParser/UBBSyntax.txt create mode 100644 UBBParser/UBBParser/UBBToken.cs create mode 100644 UBBParser/UBBParser/UBBTokenDefinition.cs create mode 100644 UBBParser/UBBtoXMLConverter.sln create mode 100644 Utility/AssemblyInfo.cs create mode 100644 Utility/GeneralUtils.cs create mode 100644 Utility/HnDGeneralUtils.cs create mode 100644 Utility/LICENSE.txt create mode 100644 Utility/SD.HnD.Utility.csproj create mode 100644 Utility/TextParser.cs diff --git a/BL/AssemblyInfo.cs b/BL/AssemblyInfo.cs new file mode 100644 index 0000000..6b138c9 --- /dev/null +++ b/BL/AssemblyInfo.cs @@ -0,0 +1,77 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("SD.HnD.BL")] +[assembly: AssemblyDescription("HnD's Business Logic Layer")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Solutions Design")] +[assembly: AssemblyProduct("HnD, a .NET 2.0 Forum system using LLBLGen Pro")] +[assembly: AssemblyCopyright("(c)2002-2006 Solutions Design")] +[assembly: AssemblyTrademark("HnD, LLBLGen and LLBLGen Pro are trademarks of Solutions Design.")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("2.0.0.0")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/BL/ForumGuiHelper.cs b/BL/ForumGuiHelper.cs new file mode 100644 index 0000000..db6bb2b --- /dev/null +++ b/BL/ForumGuiHelper.cs @@ -0,0 +1,353 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Text; +using System.Collections; +using System.Collections.Generic; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.TypedListClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.DaoClasses; + +namespace SD.HnD.BL +{ + /// + /// Class to provide essential data for the Forum Gui + /// + public class ForumGuiHelper + { + /// + /// Returns a TypedList which contains the last (amount) posted messages in + /// the forum given. For RSS production. + /// + /// limit of amount of messages to return + /// ID of forum to pull the messages for + /// typed list with data requested + public static ForumMessagesTypedList GetLastPostedMessagesInForum(int amount, int forumID) + { + ForumMessagesTypedList forumMessages = new ForumMessagesTypedList(); + PredicateExpression filter = new PredicateExpression(); + filter.Add( (ForumFields.ForumID == forumID)); + filter.AddWithAnd((ForumFields.HasRSSFeed == true)); + SortExpression sorter = new SortExpression(MessageFields.PostingDate | SortOperator.Descending); + forumMessages.Fill(amount, sorter, false, filter); + + return forumMessages; + } + + + /// + /// Returns a DataView object that contains a complete list of threads list for + /// the requested forum and required date & time interval + /// + /// ID of Forum for which the Threadlist is required + /// Limits the Threadlist to between now and; last 48 Hrs, Last Week, Last Month, Last Year + /// The minimum number of threads to fetch if there are less threads available in the limiter interval + /// The minimum number of non-sticky visible threads to show. If the # of threads is lower than + /// this number (due to the limiter value), the minNumberOfThreadsToFetch are fetched + /// If set to true, the user calling the method has the right to view threads started by others. + /// Otherwise only the threads started by the user calling the method are returned. + /// The userid of the user calling the method. + /// DataView with all the threads + public static DataView GetAllThreadsInForumAsDataView(int forumID, ThreadListInterval limiter, short minNumberOfThreadsToFetch, + short minNumberOfNonStickyVisibleThreads, bool canViewNormalThreadsStartedByOthers, int userID) + { + DateTime limiterDate; + + // convert the limiter enum to a datetime which we can use in the filters on the thread data, where we'll use the limiter date + // as a filter for the last posting date of a post in a given thread. + switch (limiter) + { + case ThreadListInterval.Last24Hours: + limiterDate = DateTime.Today.AddHours(-24); + break; + case ThreadListInterval.Last48Hours: + limiterDate = DateTime.Today.AddHours(-48); + break; + case ThreadListInterval.LastWeek: + limiterDate = DateTime.Today.AddDays(-7); + break; + case ThreadListInterval.LastMonth: + limiterDate = DateTime.Today.AddMonths(-1); + break; + case ThreadListInterval.LastYear: + limiterDate = DateTime.Today.AddYears(-1); + break; + default: + limiterDate = DateTime.Today.AddHours(-48); + break; + } + + // We'll use a dynamic list to retrieve all threads for the given forum in the right order, for the given limiter. + ResultsetFields fields = ThreadGuiHelper.BuildDynamicListForAllThreadsWithStats(); + + // now build the relations for the dynamic list. We'll join User twice: once for the startuser and one for the lastpost user. + // also, we'll join the last message to the thread. The last message is joined with a custom filter added to the relation. + RelationCollection relations = ThreadGuiHelper.BuildRelationsForAllThreadsWithStats(); + + // Set up query conditions using Predicate Expressions + // we'll keep the sticky threads filter and the forum filter in separate variables as we'll re-use them later on. + FieldCompareValuePredicate stickyThreadsFilter = (FieldCompareValuePredicate)(ThreadFields.IsSticky == true); + FieldCompareValuePredicate forumFilter = (FieldCompareValuePredicate)(ThreadFields.ForumID == forumID); + + PredicateExpression filter = new PredicateExpression(); + filter.Add(forumFilter); + // combine the following two predicates into one predicate expression, as either one of them has to be true, but as a whole combined they should + // act as a single operator to the AND operator with the forumfilter. + PredicateExpression messageLimiterSubFilter = new PredicateExpression(); + messageLimiterSubFilter.Add(stickyThreadsFilter); + messageLimiterSubFilter.AddWithOr(ThreadFields.ThreadLastPostingDate >= limiterDate); + filter.AddWithAnd(messageLimiterSubFilter); + + // if the user can't view threads started by others, filter out threads started by users different from userID + if(!canViewNormalThreadsStartedByOthers) + { + // caller can't view threads started by others: add a filter so that threads not started by calling user aren't enlisted. + // however sticky threads are always returned so the filter contains a check so the limit is only applied on threads which aren't sticky + PredicateExpression threadsByOthersFilter = new PredicateExpression(); + threadsByOthersFilter.Add(ThreadFields.StartedByUserID==userID); + // add a filter for sticky threads, add it with 'OR', so sticky threads are always accepted + threadsByOthersFilter.AddWithOr(ThreadFields.IsSticky == true); + filter.AddWithAnd(threadsByOthersFilter); + } + + //Set up the sort expressions + SortExpression sorter = new SortExpression(ThreadFields.IsSticky | SortOperator.Descending); + sorter.Add(ThreadFields.IsClosed | SortOperator.Ascending); + sorter.Add(ThreadFields.ThreadLastPostingDate | SortOperator.Descending); + + DataTable threads = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + + // Get the data by fetching the dynamic list into the datatable using the filter and the sorter we just setup. + dao.GetMultiAsDataTable(fields, threads, 0, sorter, filter, relations, true, null, null, 0, 0); + + // count # non-sticky threads. If it's below a given minimum, refetch everything, but now don't fetch on date filtered but at least the + // set minimum. Do this ONLY if the user can view other user's threads. If that's NOT the case, don't refetch anything. + DataView stickyThreads = new DataView(threads, ThreadFieldIndex.IsSticky.ToString() + "=false", "", DataViewRowState.CurrentRows); + if((stickyThreads.Count < minNumberOfNonStickyVisibleThreads) && canViewNormalThreadsStartedByOthers) + { + // not enough threads available, fetch again, + threads = new DataTable(); + + // first fetch the sticky threads. + filter = new PredicateExpression(); + filter.Add(forumFilter); + filter.AddWithAnd(stickyThreadsFilter); + sorter = new SortExpression(ThreadFields.ThreadLastPostingDate | SortOperator.Descending); + dao.GetMultiAsDataTable(fields, threads, 0, sorter, filter, relations, true, null, null, 0, 0); + + // then fetch the rest. Fetch it into the same datatable object to append the rows to the already fetched sticky threads (if any) + stickyThreadsFilter.Value=false; + dao.GetMultiAsDataTable(fields, threads, minNumberOfThreadsToFetch, sorter, filter, relations, true, null, null, 0, 0); + + // sort closed threads to the bottom. + return new DataView(threads, string.Empty, ThreadFieldIndex.IsClosed.ToString() + " ASC", DataViewRowState.CurrentRows); + } + else + { + return threads.DefaultView; + } + } + + + /// + /// Gets all forum data with section name in a typedlist. Sorted on Section.OrderNo, Section.SectionName, Forum.OrderNo, Forum.ForumName. + /// + /// Filled typedlist with all forum names / forumIDs and their containing section's name, sorted on Sectionname, and then forumname + public static ForumsWithSectionNameTypedList GetAllForumsWithSectionNames() + { + ForumsWithSectionNameTypedList toReturn = new ForumsWithSectionNameTypedList(); + SortExpression sorter = new SortExpression(); + sorter.Add(SectionFields.OrderNo | SortOperator.Ascending); + sorter.Add(SectionFields.SectionName | SortOperator.Ascending); + sorter.Add(ForumFields.OrderNo| SortOperator.Ascending); + sorter.Add(ForumFields.ForumName | SortOperator.Ascending); + + toReturn.Fill(0, sorter); + + return toReturn; + } + + + /// + /// Gets all forum entities which belong to a given section. + /// + /// The section ID from which forums should be retrieved + /// Entity collection with entities for all forums in this section sorted alphabitacally + public static ForumCollection GetAllForumsInSection(int sectionID) + { + //create the filter with the ID passed to the method. + PredicateExpression filter = new PredicateExpression(ForumFields.SectionID == sectionID); + + // Sort forums on orderno ascending, then on name alphabetically + SortExpression sorter = new SortExpression(ForumFields.OrderNo | SortOperator.Ascending); + sorter.Add(ForumFields.ForumName | SortOperator.Ascending); + + ForumCollection toReturn = new ForumCollection(); + toReturn.GetMulti(filter, 0, sorter); + return toReturn; + } + + + /// + /// Retrieves for all available sections all forums with all relevant statistical information. This information is stored per forum in a + /// DataView which is stored in the returned Dictionary, with the SectionID where the forum is located in as Key. + /// + /// SectionCollection with all available sections + /// List of accessable forums IDs. + /// The forums for which the calling user can view other users' threads. Can be null + /// The userid of the calling user. + /// + /// Dictionary with per key (sectionID) a dataview with forum information of all the forums in that section. + /// + /// Uses dataviews because a dynamic list is executed to retrieve the information for the forums, which include aggregate info about + /// # of posts. + public static Dictionary GetAllAvailableForumsDataViews(SectionCollection availableSections, List accessableForums, + List forumsWithThreadsFromOthers, int userID) + { + Dictionary toReturn = new Dictionary(); + + // return an empty list, if the user does not have a valid list of forums to access + if (accessableForums == null || accessableForums.Count <= 0) + { + return toReturn; + } + + // fetch all forums with statistics in a dynamic list, while filtering on the list of accessable forums for this user. + // Also filter on the threads viewable by the passed in userid, which is the caller of the method. If a forum isn't in the list of + // forumsWithThreadsFromOthers, only the sticky threads and the threads started by userid should be counted / taken into account. + PredicateExpression threadFilter = new PredicateExpression(); + if((forumsWithThreadsFromOthers!=null) && (forumsWithThreadsFromOthers.Count > 0)) + { + PredicateExpression onlyOwnThreadsFilter = new PredicateExpression(); + + // accept only those threads who aren't in the forumsWithThreadsFromOthers list and which are either started by userID or sticky. + // the filter on the threads not in the forums listed in the forumsWithThreadsFromOthers + if(forumsWithThreadsFromOthers.Count == 1) + { + // optimization, specify the only value instead of the range, so we won't get a WHERE Field IN (@param) query which is slow on some + // databases, but we'll get a WHERE Field == @param + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers[0])); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers[0]); + } + else + { + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers)); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers); + } + // the filter on either sticky or threads started by the calling user + onlyOwnThreadsFilter.AddWithAnd(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID==userID)); + threadFilter.AddWithOr(onlyOwnThreadsFilter); + } + else + { + // there are no forums enlisted in which the user has the right to view threads from others. So just filter on + // sticky threads or threads started by the calling user. + threadFilter.Add(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == userID)); + } + ResultsetFields fields = new ResultsetFields(8); + fields.DefineField(ForumFields.ForumID, 0); + fields.DefineField(ForumFields.ForumName, 1); + fields.DefineField(ForumFields.ForumDescription, 2); + fields.DefineField(ForumFields.ForumLastPostingDate, 3); + // add a scalar query which retrieves the # of threads in the specific forum. Utilizes an index on the FK field to forum in thread + // this will result in the query: + // ( + // SELECT COUNT(ThreadID) FROM Thread + // WHERE ForumID = Forum.ForumID AND threadfilter. + // ) As AmountThreads + fields.DefineField(new EntityField("AmountThreads", + new ScalarQueryExpression(ThreadFields.ThreadID.SetAggregateFunction(AggregateFunction.Count), + new PredicateExpression(ThreadFields.ForumID == ForumFields.ForumID).AddWithAnd(threadFilter))), 4); + + // add a scalar query which retrieves the # of messages in the threads of this forum. Utilizies an index on the FK field in thread to forum. + // this will result in the query: + // ( + // SELECT COUNT(MessageID) FROM Message + // WHERE ThreadID IN + // ( + // SELECT ThreadID FROM Thread WHERE ForumID = Forum.ForumID AND threadfilter + // ) + // ) AS AmountMessages + fields.DefineField(new EntityField("AmountMessages", + new ScalarQueryExpression(MessageFields.MessageID.SetAggregateFunction(AggregateFunction.Count), + new FieldCompareSetPredicate( + MessageFields.ThreadID, // field to compare with the results in the IN clause + ThreadFields.ThreadID, // field to select in the select inside the IN clause + SetOperator.In, // operator, + new PredicateExpression(ThreadFields.ForumID == ForumFields.ForumID).AddWithAnd(threadFilter) // the filter for the subquery inside the IN clause + ))), 5); // rest of the DefineField method. + + fields.DefineField(ForumFields.HasRSSFeed, 6); + fields.DefineField(ForumFields.SectionID, 7); + + DataTable results = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + + // sort per section: orderno and name, then per forum: orderno and name, so the views are already sorted automatically. + SortExpression sorter = new SortExpression(); + sorter.Add(ForumFields.OrderNo | SortOperator.Ascending); + sorter.Add(ForumFields.ForumName | SortOperator.Ascending); + + // use a field compare range predicate to filter on the forums accessable to the user + dao.GetMultiAsDataTable(fields, results, 0, sorter, (ForumFields.ForumID == accessableForums), null, true, null, null, 0, 0); + + // Now per section create a new DataView in memory using in-memory filtering on the DataTable. + foreach(SectionEntity section in availableSections) + { + // Create view for current section and filter out rows we don't want. Do this with in-memory filtering of the dataview, so we don't + // have to execute multiple queries. + DataView forumsInSection = new DataView(results, "SectionID=" + section.SectionID, string.Empty, DataViewRowState.CurrentRows); + // add to sorted list with SectionID as key + toReturn.Add(section.SectionID, forumsInSection); + } + + // return the dictionary + return toReturn; + } + + + /// + /// Returns a ForumEntity of the given forum + /// + /// ForumID of forum which data should be read + /// forum entity with the data requested, or null if not found + public static ForumEntity GetForum(int forumID) + { + ForumEntity toReturn = new ForumEntity(forumID); + if(toReturn.Fields.State!=EntityState.Fetched) + { + return null; + } + return toReturn; + } + } +} diff --git a/BL/ForumManager.cs b/BL/ForumManager.cs new file mode 100644 index 0000000..83779f8 --- /dev/null +++ b/BL/ForumManager.cs @@ -0,0 +1,247 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Text; +using System.Collections; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.FactoryClasses; + +namespace SD.HnD.BL +{ + /// + /// General forum management class. + /// + public static class ForumManager + { + /// + /// Creates a new forum in the system, and locates this forum in the section iSectionID. + /// + /// The section ID. + /// Name of the forum. + /// The forum description. + /// True if the forum has an RSS feed. + /// The ID of the default support queue for this forum. Can be null. + /// The default thread list interval. + /// The order no for the section. Sections are sorted ascending on orderno. + /// Max. size of an attachment. + /// The max no of attachments per message. + /// The new thread welcome text, as shown when a new thread is created. Can be null. + /// The new thread welcome text as HTML, is null when newThreadWelcomeText is null or empty. + /// + /// ForumID of new forum or 0 if something went wrong. + /// + public static int CreateNewForum(int sectionID, string forumName, string forumDescription, bool hasRSSFeed, int? defaultSupportQueueID, + int defaultThreadListInterval, short orderNo, int maxAttachmentSize, short maxNoOfAttachmentsPerMessage, + string newThreadWelcomeText, string newThreadWelcomeTextAsHTML) + { + ForumEntity newForum = new ForumEntity(); + newForum.SectionID = sectionID; + newForum.ForumDescription = forumDescription; + newForum.ForumName = forumName; + newForum.HasRSSFeed = hasRSSFeed; + newForum.DefaultSupportQueueID = defaultSupportQueueID; + newForum.DefaultThreadListInterval = Convert.ToByte(defaultThreadListInterval); + newForum.OrderNo = orderNo; + newForum.MaxAttachmentSize = maxAttachmentSize; + newForum.MaxNoOfAttachmentsPerMessage = maxNoOfAttachmentsPerMessage; + newForum.NewThreadWelcomeText = newThreadWelcomeText; + newForum.NewThreadWelcomeTextAsHTML = newThreadWelcomeTextAsHTML; + bool result = newForum.Save(); + if(result) + { + // succeeded + return newForum.ForumID; + } + else + { + return 0; + } + } + + + /// + /// Modifies the given forum with the information given + /// + /// ID of forum to modify + /// ID of section to locate this forum in + /// Name of the forum + /// Short description of the forum. + /// True if the forum has an RSS feed. + /// The ID of the default support queue for this forum. Can be null. + /// The default thread list interval. + /// The order no for the section. Sections are sorted ascending on orderno. + /// Max. size of an attachment. + /// The max no of attachments per message. + /// The new thread welcome text, as shown when a new thread is created. Can be null. + /// The new thread welcome text as HTML, is null when newThreadWelcomeText is null or empty. + /// True if succeeded, false otherwise + public static bool ModifyForum(int forumID, int sectionID, string forumName, string forumDescription, bool hasRSSFeed, int? defaultSupportQueueID, + int defaultThreadListInterval, short orderNo, int maxAttachmentSize, short maxNoOfAttachmentsPerMessage, + string newThreadWelcomeText, string newThreadWelcomeTextAsHTML) + { + ForumEntity forum = ForumGuiHelper.GetForum(forumID); + if(forum==null) + { + // not found + return false; // doesn't exist + } + forum.SectionID = sectionID; + forum.ForumDescription = forumDescription; + forum.ForumName = forumName; + forum.HasRSSFeed = hasRSSFeed; + forum.DefaultSupportQueueID = defaultSupportQueueID; + forum.DefaultThreadListInterval = Convert.ToByte(defaultThreadListInterval); + forum.OrderNo = orderNo; + forum.MaxAttachmentSize = maxAttachmentSize; + forum.MaxNoOfAttachmentsPerMessage = maxNoOfAttachmentsPerMessage; + forum.NewThreadWelcomeText = newThreadWelcomeText; + forum.NewThreadWelcomeTextAsHTML = newThreadWelcomeTextAsHTML; + return forum.Save(); + } + + + /// + /// Deletes the given forum from the system, including all threads in this forum and messages in those threads. + /// + /// Forum ID. + /// True if succeeded, false otherwise + public static bool DeleteForum(int forumID) + { + // first all threads in this forum have to be removed, then this forum should be removed. Do this in one transaction. + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "DeleteForum"); + try + { + PredicateExpression forumFilter = new PredicateExpression(); + forumFilter.Add((ForumFields.ForumID == forumID)); + + // remove all threads in this forum + ThreadManager.DeleteAllThreadsInForum(forumID, trans); + + // remove all ForumRoleForumActionRight entities for this forum + ForumRoleForumActionRightCollection forumRoleActionRights = new ForumRoleForumActionRightCollection(); + trans.Add(forumRoleActionRights); + forumRoleActionRights.DeleteMulti(ForumRoleForumActionRightFields.ForumID == forumID); + + // remove the forum entity. do this by executing a direct delete statement on the database + ForumCollection forums = new ForumCollection(); + trans.Add(forums); + forums.DeleteMulti(forumFilter); + trans.Commit(); + return true; + } + catch + { + // exception occured, rollback + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Creates a new thread in the given forum and places the passed in message as the first message in the thread. + /// Caller should validate input parameters. + /// + /// Forum wherein the new thread will be placed + /// User who started this thread + /// Subject of the thread + /// First message of the thread + /// Message text as HTML + /// Flag if the thread is sticky / pinned (true) or not (false) + /// IP address of user calling this method + /// The ID of the default support queue for this forum. If not null, the thread created will be + /// added to the support queue with the ID specified. + /// The message ID of the new message, which is the start message in the thread. + /// ThreadID if succeeded, 0 if not. + public static int CreateNewThreadInForum(int forumID, int userID, string subject, string messageText, string messageAsHTML, bool isSticky, + string userIDIPAddress, int? defaultSupportQueueID, bool subscribeToThread, out int messageID) + { + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "NewThread"); + try + { + DateTime postDate = DateTime.Now; + + ThreadEntity newThread = new ThreadEntity(); + newThread.ForumID = forumID; + newThread.IsClosed = false; + newThread.IsSticky = isSticky; + newThread.StartedByUserID = userID; + newThread.Subject = subject; + newThread.ThreadLastPostingDate = postDate; + + if(defaultSupportQueueID.HasValue) + { + // a support queue has been specified as the default support queue for this forum. Add the new thread to this support queue. + SupportQueueThreadEntity supportQueueThread = new SupportQueueThreadEntity(); + supportQueueThread.QueueID = defaultSupportQueueID.Value; + supportQueueThread.PlacedInQueueByUserID = userID; + supportQueueThread.PlacedInQueueOn = DateTime.Now; + // assign the Thread property to the newly created thread entity, so this supportqueuethreadentity will be part of the graph + // of objects which will be saved. + supportQueueThread.Thread = newThread; + } + + DateTime postingDate = DateTime.Now; + MessageEntity newMessage = new MessageEntity(); + newMessage.MessageText = messageText; + newMessage.MessageTextAsHTML = messageAsHTML; + newMessage.PostedByUserID = userID; + newMessage.PostingDate = postingDate; + newMessage.PostedFromIP = userIDIPAddress; + newMessage.Thread = newThread; + + // add the newMessage entity to the transaction object. All entities saved recursively will be added automatically + trans.Add(newMessage); + + // save the complete graph + newMessage.Save(true); + + messageID = newMessage.MessageID; + int threadID = newMessage.ThreadID; + + // update thread statistics, this is the task for the message manager, and we pass the transaction object so the actions will run in + // the same transaction. + MessageManager.UpdateStatisticsAfterMessageInsert(threadID, userID, trans, postingDate, false, subscribeToThread); + + trans.Commit(); + return newThread.ThreadID; + } + catch(Exception) + { + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + } +} diff --git a/BL/Globals.cs b/BL/Globals.cs new file mode 100644 index 0000000..b6232d6 --- /dev/null +++ b/BL/Globals.cs @@ -0,0 +1,167 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; + +namespace SD.HnD.BL +{ + /// + /// Global values for Tiny forum. + /// + public static class Globals + { + /// + /// Version of HnD + /// + public static readonly string Version = "2.1"; + /// + /// Build of HnD + /// + public static readonly string Build = "12172008"; + /// + /// Release type of this version + /// + public static readonly string ReleaseType = "Final"; + /// + /// The UserID to deny login rights, since this is the Anonymous Coward user, which is + /// used for non-logged in users. + /// + public static readonly int UserIDToDenyLogin = 0; + } + + + /// + /// Class with solely readonly static strings for cache keys used with the ASP.NET cache of the forum system. + /// + public static class CacheKeys + { + /// + /// The key to use to obtain and store the cached sections + /// + public static readonly string AllSections = "AllSections"; + /// + /// The key to use to obtain and store a cached forum entity + /// + public static readonly string SingleForum = "SingleForum"; + /// + /// The key to use to obtain and store the cached IP Bans structure (dictionary with per range the ip addresses for the ip bans). + /// + public static readonly string AllIPBans = "AllIPBans"; + /// + /// The key to use to obtain and store the cached support queue entities. + /// + public static readonly string AllSupportQueues = "AllSupportQueues"; + /// + /// The key to use to obtain and store the cached system data entity. + /// + public static readonly string SystemData = "SystemData"; + } + + + // enums + /// + /// Enum for specifying the ordering of the search results. + /// + public enum SearchResultsOrderSetting:int + { + LastPostDateDescending, + LastPostDateAscending, + ForumAscending, + ForumDescending, + ThreadSubjectAscending, + ThreadSubjectDescending + } + + + /// + /// Enum for defining the search target for a search. + /// + public enum SearchTarget : int + { + MessageText, + ThreadSubject, + MessageTextAndThreadSubject + } + + + /// + /// Audit actions + /// + public enum AuditActions:int + { + AuditLogin=1, + AuditNewMessage=2, + AuditNewThread=3, + AuditAlteredMessage=4, + AuditEditMemo=5, + AuditApproveAttachment=6 + } + + + /// + /// ThreadListInterval constants. + /// + public enum ThreadListInterval:byte + { + Last24Hours = 1, + Last48Hours, + LastWeek, + LastMonth, + LastYear + } + + /// + /// ActionRights constants. The Application object will hold a cached hashtable with + /// the actionrights definitions from the database. These are defined system wide, and + /// are not mutated at runtime. + /// + public enum ActionRights:int + { + AddAndEditMessage = 1, + AccessForum, + UserManagement, + SecurityManagement, + EditDeleteOtherUsersMessages, + ForumSpecificThreadManagement, + SystemManagement, + AddAndEditMessageInSticky, + SystemWideThreadManagement, + AddNormalThread, // 10 + AddStickyThread, + EditThreadMemo, + FlagThreadAsDone, + QueueContentManagement, + ViewNormalThreadsStartedByOthers, // 15 + ManageOtherUsersAttachments, + AddAttachment, + GetsAttachmentsApprovedAutomatically, + ApproveAttachment + // Add more here. Check the comma! + } + + /// + /// MailTemplate constants. The generated emails supported by the application. A dedicated helper + /// will get the corresponding template file path + /// + public enum EmailTemplate : int + { + RegistrationReply = 1, + ThreadUpdatedNotification = 2 + } +} diff --git a/BL/GuiHelper.cs b/BL/GuiHelper.cs new file mode 100644 index 0000000..b5609c5 --- /dev/null +++ b/BL/GuiHelper.cs @@ -0,0 +1,73 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Data; +using System.Globalization; +using System.Configuration; +using System.Xml.Xsl; +using System.IO; +using System.Text.RegularExpressions; + +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.EntityClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.BL +{ + /// + /// General helper class for the GUI of HnD. This class provides + /// general purpose routines to get special things done for the gui, but which + /// are not that important, BL wise. The class is still in the BL-tier, because + /// it provides a service to the GUI, but isn't part of it. + /// + public static class GuiHelper + { + /// + /// Loads the noise words into hashtable. Noise words are words which can be ignored during message indexing and searches. + /// + /// Path to the datafiles folder + /// A hashtable with all the noisewords found in the file Datafiles/Noise.txt + public static Hashtable LoadNoiseWordsIntoHashtable(string dataFilesPath) + { + string fullPath = Path.Combine(dataFilesPath, "Noise.txt"); + StreamReader reader = new StreamReader(fullPath); + bool eofReached = false; + Hashtable noiseWords = new Hashtable(256); + while(!eofReached) + { + string noiseWord = reader.ReadLine(); + eofReached=(noiseWord==null); + if(!eofReached) + { + if(!noiseWords.ContainsKey(noiseWord)) + { + noiseWords.Add(noiseWord, null); + } + } + } + + return noiseWords; + } + } +} \ No newline at end of file diff --git a/BL/LICENSE.txt b/BL/LICENSE.txt new file mode 100644 index 0000000..6e812ec --- /dev/null +++ b/BL/LICENSE.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/BL/MessageGuiHelper.cs b/BL/MessageGuiHelper.cs new file mode 100644 index 0000000..81544e8 --- /dev/null +++ b/BL/MessageGuiHelper.cs @@ -0,0 +1,314 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL; +using System.Collections.Generic; + +namespace SD.HnD.BL +{ + /// + /// Class to provide essential data for the Message Gui + /// + public static class MessageGuiHelper + { + /// + /// Gets the number of postings in all threads of all forums on this system. + /// + /// the total of all posts on the entire forum system + public static int GetTotalNumberOfMessages() + { + MessageCollection messages = new MessageCollection(); + return messages.GetDbCount(); + } + + + /// + /// Gets the total number of attachments to approve. + /// + /// The accessable forums by the user calling. + /// The forums the calling user has attachment approval rights. + /// The forums the calling user can view normal threads from others. + /// The user ID of the calling user. + /// the # of attachments with the approval state which are approvable by the calling user + public static int GetTotalNumberOfAttachmentsToApprove(List accessableForums, List forumsWithApprovalRight, + List forumsWithThreadsFromOthers, int userID) + { + if((accessableForums == null) || (accessableForums.Count <= 0)) + { + // doesn't have access to any forum, return + return 0; + } + if((forumsWithApprovalRight == null) || (forumsWithApprovalRight.Count <= 0)) + { + // doesn't have a forum with attachment approval right + return 0; + } + + // we'll use a GetDBCount call, where we'll specify a filter. + + // we've to join attachment - message - thread, so we've to create a RelationCollection with the necessary relations. + RelationCollection relations = new RelationCollection(); + relations.Add(AttachmentEntity.Relations.MessageEntityUsingMessageID); + relations.Add(MessageEntity.Relations.ThreadEntityUsingThreadID); + + // we've to filter the list of attachments based on the forums accessable by the calling user, the list of forums the calling user has approval rights + // on and by the forums on which the user can see other user's threads. We'll create a predicate expression for this, and will add for each of these + // filters a separate predicate to this predicate expression and specify AND, so they all have to be true + PredicateExpression filter = CreateAttachmentFilter(accessableForums, forumsWithApprovalRight, forumsWithThreadsFromOthers, userID, false); + + AttachmentCollection attachments = new AttachmentCollection(); + return attachments.GetDbCount(filter, relations); + } + + + /// + /// Gets the message entity with the ID passed in. + /// + /// The message ID. + /// Filled messageentity if found, otherwise null + public static MessageEntity GetMessage(int messageID) + { + // load the entity from the database + MessageEntity message = new MessageEntity(messageID); + + //check if the entity is new (not found in the database), then return null. + if(message.IsNew == true) + { + return null; + } + + return message; + } + + + /// + /// Gets the attachments for the message with the messageid passed in. Attachments are sorted by AddedOn ascending. + /// The result is returned as a dynamic list, because we don't want the actual attachment data. + /// + /// The message ID. + /// Dataview with 0 or more attachments related to the message with the id passed in. The rows don't contain the actual attachment data + public static DataView GetAttachmentsAsDataView(int messageID) + { + ResultsetFields fields = new ResultsetFields(5); + fields.DefineField(AttachmentFields.AttachmentID, 0); + fields.DefineField(AttachmentFields.Filename, 1); + fields.DefineField(AttachmentFields.Approved, 2); + fields.DefineField(AttachmentFields.Filesize, 3); + fields.DefineField(AttachmentFields.AddedOn, 4); + + DataTable attachments = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + SortExpression sorter = new SortExpression(AttachmentFields.AddedOn | SortOperator.Ascending); + dao.GetMultiAsDataTable(fields, attachments, 0, sorter, (AttachmentFields.MessageID == messageID), null, true, null, null, 0, 0); + return attachments.DefaultView; + } + + + /// + /// Gets the attachment with the attachmentid passed in + /// + /// The attachment ID. + /// the attachment entity or null if not found + public static AttachmentEntity GetAttachment(int attachmentID) + { + AttachmentEntity toReturn = new AttachmentEntity(attachmentID); + if(toReturn.IsNew) + { + // not found + return null; + } + return toReturn; + } + + + /// + /// Gets the message of the attachment with the attachmentid passed in. + /// + /// The attachment ID. + /// MessageEntity if found, otherwise null. MessageEntity has its Thread entity prefetched + public static MessageEntity GetMessageWithAttachmentLogic(int attachmentID) + { + // we're going to use a message collection so we can use a filter on a related entity. + // we're not going to utilize lazy loading, as that would require the attachment to be loaded into memory, but that could potentially be expensive + // for memory, so we'll avoid that + MessageCollection messages = new MessageCollection(); + RelationCollection relations = new RelationCollection(); + relations.Add(MessageEntity.Relations.AttachmentEntityUsingMessageID); + // we're going to use a prefetch path as well, to prefetch the thread entity as well. + PrefetchPath path = new PrefetchPath((int)EntityType.MessageEntity); + path.Add(MessageEntity.PrefetchPathThread); + messages.GetMulti((AttachmentFields.AttachmentID == attachmentID), 0, null, relations, path); + if(messages.Count > 0) + { + // found it + return messages[0]; + } + else + { + // not found, + return null; + } + } + + + /// + /// Gets all attachments which have to be approved as data view, filtered on the two passed in list of forum id's. + /// It doesn't return the file contents for each attachment, it just returns the other data of each attachment, as well as some other related data. + /// + /// The accessable forums by the user calling. + /// The forums the calling user has attachment approval rights. + /// The forums the calling user can view normal threads from others. + /// The user ID of the calling user. + /// DataView with the data requested. + public static DataView GetAllAttachmentsToApproveAsDataView(List accessableForums, List forumsWithApprovalRight, + List forumsWithThreadsFromOthers, int userID) + { + if((accessableForums == null) || (accessableForums.Count <= 0)) + { + // doesn't have access to any forum, return + return null; + } + if((forumsWithApprovalRight == null) || (forumsWithApprovalRight.Count <= 0)) + { + // doesn't have a forum with attachment approval right + return null; + } + + // we'll use a dynamic list for the data to return. This is similar to GetAttachmentsAsDataView, however now we'll add more data + we'll + // filter on more things. The data we'll add is the ForumID of the thread containing the messagee the attachment is attached to, as well as + // the userid of the poster of the message the attachment is attached to, and the threadid of the thread the message is in. + ResultsetFields fields = new ResultsetFields(9); + fields.DefineField(AttachmentFields.AttachmentID, 0); + fields.DefineField(AttachmentFields.MessageID, 1); + fields.DefineField(AttachmentFields.Filename, 2); + fields.DefineField(AttachmentFields.Approved, 3); + fields.DefineField(AttachmentFields.Filesize, 4); + fields.DefineField(AttachmentFields.AddedOn, 5); + fields.DefineField(MessageFields.PostedByUserID, 6); + fields.DefineField(ThreadFields.ForumID, 7); + fields.DefineField(ThreadFields.ThreadID, 8); + + // we've to join attachment - message - thread, so we've to create a RelationCollection with the necessary relations. + RelationCollection relations = new RelationCollection(); + relations.Add(AttachmentEntity.Relations.MessageEntityUsingMessageID); + relations.Add(MessageEntity.Relations.ThreadEntityUsingThreadID); + + // we've to filter the list of attachments based on the forums accessable by the calling user, the list of forums the calling user has approval rights + // on and by the forums on which the user can see other user's threads. We'll create a predicate expression for this, and will add for each of these + // filters a separate predicate to this predicate expression and specify AND, so they all have to be true + PredicateExpression filter = CreateAttachmentFilter(accessableForums, forumsWithApprovalRight, forumsWithThreadsFromOthers, userID, false); + + DataTable attachments = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + // The results will be sorted on the date the attachments were added, ascending, so the oldest will be on top. + SortExpression sorter = new SortExpression(AttachmentFields.AddedOn | SortOperator.Ascending); + dao.GetMultiAsDataTable(fields, attachments, 0, sorter, filter, relations, true, null, null, 0, 0); + return attachments.DefaultView; + } + + + /// + /// Creates the attachment filter. The filter filters on attachments with the specified approvalstate in the threads viewable by the calling user. + /// + /// The accessable forums. + /// The forums with approval right. + /// The forums with threads from others. + /// The user ID. + /// The filter. + /// ready to use predicate expression for fetch actions on attachments with the approval state specified in the threads + /// matching the forumID's. + private static PredicateExpression CreateAttachmentFilter(List accessableForums, List forumsWithApprovalRight, + List forumsWithThreadsFromOthers, int userID, bool approvalState) + { + PredicateExpression filter = new PredicateExpression(); + + // specify the filter for the accessable forums. Do this by a fieldcomparerange predicate and filter on Thread.ForumID. As 'accessableForums' is a list + // the following statement will create a fieldcomparerange predicate for us. + if(accessableForums.Count == 1) + { + // optimization, specify the only value instead of the range, so we won't get a WHERE Field IN (@param) query which is slow on some + // databases, but we'll get a WHERE Field == @param + filter.Add(ThreadFields.ForumID == accessableForums[0]); + } + else + { + filter.Add(ThreadFields.ForumID == accessableForums); + } + // specify the filter for the forums with approval rights: + if(forumsWithApprovalRight.Count == 1) + { + // optimization, specify the only value instead of the range, so we won't get a WHERE Field IN (@param) query which is slow on some + // databases, but we'll get a WHERE Field == @param + filter.Add(ThreadFields.ForumID == forumsWithApprovalRight[0]); + } + else + { + filter.Add(ThreadFields.ForumID == forumsWithApprovalRight); + } + // Also filter on the threads viewable by the passed in userid, which is the caller of the method. If a forum isn't in the list of + // forumsWithThreadsFromOthers, only the sticky threads and the threads started by userid should be counted / taken into account. + PredicateExpression threadFilter = new PredicateExpression(); + if((forumsWithThreadsFromOthers != null) && (forumsWithThreadsFromOthers.Count > 0)) + { + PredicateExpression onlyOwnThreadsFilter = new PredicateExpression(); + + // accept only those threads who aren't in the forumsWithThreadsFromOthers list and which are either started by userID or sticky. + // the filter on the threads not in the forums listed in the forumsWithThreadsFromOthers + if(forumsWithThreadsFromOthers.Count == 1) + { + // optimization, specify the only value instead of the range, so we won't get a WHERE Field IN (@param) query which is slow on some + // databases, but we'll get a WHERE Field == @param + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers[0])); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers[0]); + } + else + { + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers)); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers); + } + // the filter on either sticky or threads started by the calling user + onlyOwnThreadsFilter.AddWithAnd(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == userID)); + threadFilter.AddWithOr(onlyOwnThreadsFilter); + } + else + { + // there are no forums enlisted in which the user has the right to view threads from others. So just filter on + // sticky threads or threads started by the calling user. + threadFilter.Add(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == userID)); + } + filter.AddWithAnd(threadFilter); + // as last filter, we'll add a filter to only get the data for attachments which aren't approved yet. + filter.AddWithAnd(AttachmentFields.Approved == false); + + return filter; + } + } +} diff --git a/BL/MessageManager.cs b/BL/MessageManager.cs new file mode 100644 index 0000000..8bd22f8 --- /dev/null +++ b/BL/MessageManager.cs @@ -0,0 +1,333 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using SD.HnD.Utility; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.DaoClasses; + +namespace SD.HnD.BL +{ + /// + /// General class for Message management related tasks + /// + public static class MessageManager + { + /// + /// Deletes the given message from the database and the complete logged history. + /// + /// The ID of the message to delete + /// True if succeeded, false otherwise + public static bool DeleteMessage(int messageID) + { + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "DeleteMessage"); + + try + { + // formulate a filter so we can re-use the delete routine for all messages in threads matching a filter. + PredicateExpression messageFilter = new PredicateExpression(MessageFields.MessageID == messageID); + + // call the routine which is used to delete 1 or more messages and related data from the db. + DeleteMessages(messageFilter, trans); + trans.Commit(); + return true; + } + catch(Exception) + { + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Deletes all messages in threads which match the passed in filter. + /// + /// The thread filter. + /// The transaction to use. + internal static void DeleteAllMessagesInThreads(PredicateExpression threadFilter, Transaction trans) + { + // fabricate the messagefilter, based on the passed in filter on threads. We do this by creating a FieldCompareSetPredicate: + // WHERE Message.ThreadID IN (SELECT ThreadID FROM Thread WHERE threadFilter) + PredicateExpression messageFilter = new PredicateExpression(); + messageFilter.Add(new FieldCompareSetPredicate(MessageFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); + DeleteMessages(messageFilter, trans); + } + + + /// + /// Deletes the messages matching the messagefilter passed in + /// + /// The message filter. + /// The transaction to use. + private static void DeleteMessages(PredicateExpression messageFilter, Transaction trans) + { + // first delete all audit info for these message. This isn't done by a batch call directly on the db, as this is a targetperentity hierarchy + // which can't be deleted directly into the database in all cases, so we first fetch the entities to delete. + AuditDataMessageRelatedCollection messageAudits = new AuditDataMessageRelatedCollection(); + trans.Add(messageAudits); + // use a fieldcompareset predicate to get the auditdata related to this message and then delete all of them using the collection. + messageAudits.GetMulti(new FieldCompareSetPredicate(AuditDataMessageRelatedFields.MessageID, MessageFields.MessageID, SetOperator.In, messageFilter)); + messageAudits.DeleteMulti(); + + // delete all attachments for this message. This can be done directly onto the db. + AttachmentCollection attachments = new AttachmentCollection(); + trans.Add(attachments); + // delete these directly from the db, using a fieldcompareset predicate + attachments.DeleteMulti(new FieldCompareSetPredicate(AttachmentFields.MessageID, MessageFields.MessageID, SetOperator.In, messageFilter)); + + // delete the message/messages + MessageCollection messages = new MessageCollection(); + trans.Add(messages); + // use the passed in filter to remove the messages + messages.DeleteMulti(messageFilter); + + // don't commit the transaction, leave that to the caller. + } + + + /// + /// Updates the given message with the message passed, and logs the user passed as the changer of this + /// message. + /// + /// ID of user who changed the message + /// ID of message which was changed + /// Changed message text + /// Changed message text in HTML + /// IP address used to make the modification. This IP address is logged with the + /// change to keep evidence who made which change from which IP address + /// Message text as XML, which is the result of the parse action on MessageText. + /// True if succeeded, false otherwise + /// This routine is migrated to LLBLGen Pro + public static bool UpdateEditedMessage(int editorUserID, int editedMessageID, string messageText, string messageAsHTML, + string editorUserIDIPAddress, string messageAsXML) + { + // now save the message. First pull it from the db + MessageEntity message = new MessageEntity(editedMessageID); + + //update the fields with the new passed values + message.MessageText = messageText; + message.MessageTextAsHTML = messageAsHTML; + message.MessageTextAsXml = messageAsXML; + return message.Save(); + } + + + /// + /// Re-parses all messages from start date till now or when amountToIndex is reached. This routine will read messagetext for a message, + /// parse it, and update the MessageTextAsXML field with the parse result. + /// + /// Amount to parse. + /// Start date. + /// If true, the HTML is also re-generated and saved. + /// the amount of messages re-parsed + public static int ReParseMessages(int amountToParse, DateTime startDate, bool reGenerateHTML, ParserData parserData) + { + // index is blocks of 100 messages. + ResultsetFields fields = new ResultsetFields(2); + fields.DefineField(MessageFields.MessageID, 0); + fields.DefineField(MessageFields.MessageText, 1); + + //filter messages with postingDate >= the passed startDate + PredicateExpression filter = new PredicateExpression(MessageFields.PostingDate >= new DateTime(startDate.Year, startDate.Month, startDate.Day, 0, 0, 0, 0)); + + if(amountToParse <= 0) + { + // If we don't have a specific amount of messasges to parse, then parse all messages posted till Now. + filter.Add(MessageFields.PostingDate <= DateTime.Now); + } + + TypedListDAO dao = new TypedListDAO(); + + bool parsingFinished = false; + int amountProcessed = 0; + int pageSize = 100; + int pageNo = 1; + + while(!parsingFinished) + { + DataTable messagesToParse = new DataTable(); + dao.GetMultiAsDataTable(fields, messagesToParse, 0, null, filter, null, true, null, null, pageNo, pageSize); + parsingFinished = (messagesToParse.Rows.Count <= 0); + + if(!parsingFinished) + { + foreach(DataRow row in messagesToParse.Rows) + { + MessageEntity directUpdater = new MessageEntity(); + directUpdater.IsNew = false; + + string messageXML = string.Empty; + string messageHTML = string.Empty; + TextParser.ReParseMessage((string)row["MessageText"], reGenerateHTML, parserData, out messageXML, out messageHTML); + + // use the directupdater entity to create an update query without fetching the entity first. + directUpdater.Fields[(int)MessageFieldIndex.MessageID].ForcedCurrentValueWrite((int)row["MessageID"]); + directUpdater.MessageTextAsXml = messageXML; + + if(reGenerateHTML) + { + directUpdater.MessageTextAsHTML=messageHTML; + } + directUpdater.Fields.IsDirty=true; + + // no transactional update. + directUpdater.Save(); + } + + amountProcessed += messagesToParse.Rows.Count; + pageNo++; + + if(amountToParse > 0) + { + parsingFinished = (amountToParse <= amountProcessed); + } + } + } + return amountProcessed; + } + + + /// + /// Deletes the attachment with the id specified. + /// + /// The attachment ID. + public static void DeleteAttachment(int attachmentID) + { + // delete the attachment directly from the db, without loading it first into memory, so the attachment won't eat up memory unnecessary. + AttachmentCollection attachments = new AttachmentCollection(); + attachments.DeleteMulti((AttachmentFields.AttachmentID == attachmentID)); + } + + + /// + /// Approves / revokes the approval of the attachment with ID passed in. + /// + /// The attachment ID. + /// the new flag value for Approved + public static void ModifyAttachmentApproval(int attachmentID, bool approved) + { + // we'll update the approved flag directly in the db, so we don't load the whole attachment into memory. + AttachmentEntity updater = new AttachmentEntity(); + AttachmentCollection attachments = new AttachmentCollection(); + updater.Approved = approved; + attachments.UpdateMulti(updater, (AttachmentFields.AttachmentID == attachmentID)); + } + + + /// + /// Adds a new attachment to the message with messageID specified. + /// + /// The message ID. + /// Name of the file. + /// The file contents. + /// the value for the approved flag + public static void AddAttachment(int messageID, string fileName, byte[] fileContents, bool approveValue) + { + AttachmentEntity newAttachment = new AttachmentEntity(); + newAttachment.MessageID = messageID; + newAttachment.Filename = fileName; + newAttachment.Filecontents = fileContents; + newAttachment.Filesize = fileContents.Length; + newAttachment.Approved = approveValue; + newAttachment.AddedOn = DateTime.Now; + + // save. + newAttachment.Save(); + } + + + /// + /// Updates the user/forum/thread statistics after a message insert. Also makes sure if the thread isn't in a queue and the forum has a default support + /// queue that the thread is added to that queue + /// + /// The thread ID. + /// The user ID. + /// The transaction to use. + /// The posting date. + /// if set to true, the thread will be added to the default queue of the forum the thread is in, if the forum + /// has a default support queue and the thread isn't already in a queue. + /// Leaves the passed in transaction open, so it doesn't commit/rollback, it just performs a set of actions inside the + /// passed in transaction. + internal static void UpdateStatisticsAfterMessageInsert(int threadID, int userID, Transaction transactionToUse, DateTime postingDate, bool addToQueueIfRequired, bool subscribeToThread) + { + // user statistics + UserEntity userUpdater = new UserEntity(); + // set the amountofpostings field to an expression so it will be increased with 1. + userUpdater.Fields[(int)UserFieldIndex.AmountOfPostings].ExpressionToApply = (UserFields.AmountOfPostings + 1); + UserCollection users = new UserCollection(); + transactionToUse.Add(users); + users.UpdateMulti(userUpdater, (UserFields.UserID == userID)); // update directly on the DB. + + // thread statistics + ThreadEntity threadUpdater = new ThreadEntity(); + threadUpdater.ThreadLastPostingDate = postingDate; + threadUpdater.MarkedAsDone = false; + ThreadCollection threads = new ThreadCollection(); + transactionToUse.Add(threads); + threads.UpdateMulti(threadUpdater, (ThreadFields.ThreadID == threadID)); + + // forum statistics. Load the forum from the DB, as we need it later on. Use a fieldcompareset predicate to fetch the forum as we don't know the + // forumID as we haven't fetched the thread + ForumCollection forums = new ForumCollection(); + transactionToUse.Add(forums); + // use a fieldcompare set predicate to select the forumid based on the thread. This filter is equal to + // WHERE ForumID == (SELECT ForumID FROM Thread WHERE ThreadID=@ThreadID) + FieldCompareSetPredicate forumFilter = new FieldCompareSetPredicate( + ForumFields.ForumID, ThreadFields.ForumID, SetOperator.Equal, (ThreadFields.ThreadID == threadID)); + forums.GetMulti(forumFilter); + ForumEntity containingForum = null; + if(forums.Count>0) + { + // forum found. There's just one. + containingForum = forums[0]; + containingForum.ForumLastPostingDate = postingDate; + // save the forum. Just save the collection + forums.SaveMulti(); + } + + if(addToQueueIfRequired) + { + // If the thread involved isn't in a queue, place it in the default queue of the forum (if applicable) + SupportQueueEntity containingQueue = SupportQueueGuiHelper.GetQueueOfThread(threadID, transactionToUse); + if((containingQueue == null) && (containingForum != null) && (containingForum.DefaultSupportQueueID.HasValue)) + { + // not in a queue, and the forum has a default queue. Add the thread to the queue of the forum + SupportQueueManager.AddThreadToQueue(threadID, containingForum.DefaultSupportQueueID.Value, userID, transactionToUse); + } + } + + //subscribe to thread if indicated + if(subscribeToThread) + { + UserManager.AddThreadToSubscriptions(threadID, userID, transactionToUse); + } + } + } +} diff --git a/BL/SD.HnD.BL.csproj b/BL/SD.HnD.BL.csproj new file mode 100644 index 0000000..19cf5e5 --- /dev/null +++ b/BL/SD.HnD.BL.csproj @@ -0,0 +1,210 @@ + + + + Local + 8.0.50727 + 2.0 + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A} + Debug + AnyCPU + + + + + SD.HnD.BL + + + JScript + Grid + IE50 + false + Library + SD.HnD.BL + OnBuildSuccess + + + + + + + v3.5 + 2.0 + http://localhost/SD.HnD.BL/ + true + Web + true + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + true + false + true + + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + AllRules.ruleset + + + bin\Release\ + false + 285212672 + false + + + TRACE + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + AllRules.ruleset + + + + False + ..\RuntimeLibraries\SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll + + + System + + + + System.Data + + + System.Web + + + System.XML + + + {43C8451A-A377-4589-BF7D-73BE386E7B4D} + SD.HnD.DAL + + + Util + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + + + \ No newline at end of file diff --git a/BL/Searcher.cs b/BL/Searcher.cs new file mode 100644 index 0000000..9261f23 --- /dev/null +++ b/BL/Searcher.cs @@ -0,0 +1,321 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Data; +using System.Text; +using System.Globalization; + +using System.Xml; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.TypedListClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.DaoClasses; + +using SD.HnD.Utility; +using System.Collections.Generic; +using System.Data.Common; + +namespace SD.HnD.BL +{ + /// + /// Generic searcher. + /// This searcher class uses the MS full text search engine to find matching messages. + /// + public static class Searcher + { + /// + /// Does the search using MS Full text search + /// + /// Search string. + /// Forum Ids of forums to search into. + /// Order first element setting. + /// Order second element setting. + /// The forums with threads from others. + /// The userid of the calling user. + /// The target to search. + /// + /// TypedList filled with threads matching the query. + /// + public static SearchResultTypedList DoSearch(string searchString, List forumIDs, SearchResultsOrderSetting orderFirstElement, + SearchResultsOrderSetting orderSecondElement, List forumsWithThreadsFromOthers, int userID, SearchTarget targetToSearch) + { + // the search utilizes full text search. It performs a CONTAINS upon the MessageText field of the Message entity. + string searchTerms = PrepareSearchTerms(searchString); + bool searchMessageText = (targetToSearch == SearchTarget.MessageText) || (targetToSearch == SearchTarget.MessageTextAndThreadSubject); + bool searchSubject = (targetToSearch == SearchTarget.ThreadSubject) || (targetToSearch == SearchTarget.MessageTextAndThreadSubject); + if(!(searchSubject || searchMessageText)) + { + // no target specified, select message + searchMessageText = true; + } + + PredicateExpression mainFilter = new PredicateExpression(); + PredicateExpression searchTermFilter = new PredicateExpression(); + + if(searchMessageText) + { + // Message contents filter + searchTermFilter.Add(new FieldCompareSetPredicate(ThreadFields.ThreadID, MessageFields.ThreadID, + SetOperator.In, new FieldFullTextSearchPredicate(MessageFields.MessageText, FullTextSearchOperator.Contains, searchTerms))); + } + if(searchSubject) + { + // Thread subject filter + if(searchMessageText) + { + searchTermFilter.AddWithOr(new FieldFullTextSearchPredicate(ThreadFields.Subject, FullTextSearchOperator.Contains, searchTerms)); + } + else + { + searchTermFilter.Add(new FieldFullTextSearchPredicate(ThreadFields.Subject, FullTextSearchOperator.Contains, searchTerms)); + } + } + mainFilter.Add(searchTermFilter); + + // add forumid filter + mainFilter.AddWithAnd(ForumFields.ForumID == forumIDs); + + // Also filter on the threads viewable by the passed in userid, which is the caller of the method. If a forum isn't in the list of + // forumsWithThreadsFromOthers, only the sticky threads and the threads started by userid should be counted / taken into account. + PredicateExpression threadFilter = new PredicateExpression(); + if((forumsWithThreadsFromOthers != null) && (forumsWithThreadsFromOthers.Count > 0)) + { + PredicateExpression onlyOwnThreadsFilter = new PredicateExpression(); + + // accept only those threads who aren't in the forumsWithThreadsFromOthers list and which are either started by userID or sticky. + // the filter on the threads not in the forums listed in the forumsWithThreadsFromOthers + if(forumsWithThreadsFromOthers.Count == 1) + { + // optimization, specify the only value instead of the range, so we won't get a WHERE Field IN (@param) query which is slow on some + // databases, but we'll get a WHERE Field == @param + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers[0])); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers[0]); + } + else + { + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers)); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers); + } + // the filter on either sticky or threads started by the calling user + onlyOwnThreadsFilter.AddWithAnd(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == userID)); + threadFilter.AddWithOr(onlyOwnThreadsFilter); + } + else + { + // there are no forums enlisted in which the user has the right to view threads from others. So just filter on + // sticky threads or threads started by the calling user. + threadFilter.Add(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == userID)); + } + + mainFilter.AddWithAnd(threadFilter); + + ISortExpression sorter = new SortExpression(); + // add first element + sorter.Add(CreateSearchSortClause(orderFirstElement)); + if(orderSecondElement != orderFirstElement) + { + sorter.Add(CreateSearchSortClause(orderSecondElement)); + } + + SearchResultTypedList results = new SearchResultTypedList(false); + + try + { + // get the data from the db. + results.Fill(500, sorter, false, mainFilter); + } + catch + { + // probably an error with the search words / user error. Swallow for now, which will result in an empty resultset. + } + + return results; + } + + + /// + /// Prepares the search terms. + /// + /// Search terms. + /// search terms string, prepare for CONTAINS usage. + private static string PrepareSearchTerms(string searchTerms) + { + ArrayList termsToProcess = new ArrayList(); + string[] terms = searchTerms.Split(' '); + // now traverse from front to back. Collide any sequence of terms where the start term starts with a '"' and the end term ends with a '"'. + for(int i=0;i 0) + { + operatorSeenLastIteration = true; + toReturn.AppendFormat(" {0} ", term); + } + continue; + case "not": + // emit an operator if none seen, and make the next element think an operator was just emitted + if(i > 0) + { + if(!operatorSeenLastIteration) + { + // last iteration wasn't an operator, emit 'AND' + toReturn.Append(" AND "); + } + } + operatorSeenLastIteration = true; + break; + default: + // not an operator nor 'not', so emit an operator if we have to. + if(i > 0) + { + if(!operatorSeenLastIteration) + { + // last iteration wasn't an operator, emit 'AND' + toReturn.Append(" AND "); + } + operatorSeenLastIteration = false; + } + break; + } + if(term.StartsWith("*") || term.EndsWith("*")) + { + // wildcard without proper quotes + toReturn.AppendFormat(" \"{0}\" ", term); + } + else + { + toReturn.AppendFormat(" {0} ", term); + } + } + + return toReturn.ToString(); + } + + + /// + /// Creates the search sort clause for the element passed in + /// + /// Element. + /// SortClause object to be used in a sort expression + private static ISortClause CreateSearchSortClause(SearchResultsOrderSetting element) + { + ISortClause toReturn = null; + switch(element) + { + case SearchResultsOrderSetting.ForumAscending: + toReturn = (ForumFields.ForumName | SortOperator.Ascending); + break; + case SearchResultsOrderSetting.ForumDescending: + toReturn = (ForumFields.ForumName | SortOperator.Descending); + break; + case SearchResultsOrderSetting.LastPostDateAscending: + toReturn = (ThreadFields.ThreadLastPostingDate | SortOperator.Ascending); + break; + case SearchResultsOrderSetting.LastPostDateDescending: + toReturn = (ThreadFields.ThreadLastPostingDate | SortOperator.Descending); + break; + case SearchResultsOrderSetting.ThreadSubjectAscending: + toReturn = (ThreadFields.Subject | SortOperator.Ascending); + break; + case SearchResultsOrderSetting.ThreadSubjectDescending: + toReturn = (ThreadFields.Subject | SortOperator.Descending); + break; + } + + return toReturn; + } + } +} diff --git a/BL/SectionGuiHelper.cs b/BL/SectionGuiHelper.cs new file mode 100644 index 0000000..0baefe9 --- /dev/null +++ b/BL/SectionGuiHelper.cs @@ -0,0 +1,117 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Collections; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.DaoClasses; + + +namespace SD.HnD.BL +{ + /// + /// Class to provide essential data for the Section Gui. + /// + public static class SectionGuiHelper + { + /// + /// Constructs a DataView from the datatable which contains all sections available, plus the # of forums in the section. + /// Sections and forums are sorted on OrderNo ascending, then on Name ascending. + /// + /// If set to true, empty sections are ignored. + /// + /// DataView with all the sections available, including statistics, directly bindable to webcontrols + /// + public static DataView GetAllSectionsWStatisticsAsDataView(bool excludeEmptySections) + { + ResultsetFields fields = new ResultsetFields(5); + fields.DefineField(SectionFields.SectionID, 0); + fields.DefineField(SectionFields.SectionName, 1); + fields.DefineField(SectionFields.SectionDescription, 2); + fields.DefineField(SectionFields.OrderNo, 3); + // as fifth field, we'll add a scalarquery expression. This scalar query expression will simply do a count on the # of forumIDs in + // the forum table for the current section. This will result in the query: + // ( + // SELECT COUNT(ForumID) + // FROM Forum + // WHERE Forum.SectionID = Section.SectionID + // ) AS AmountForums + fields.DefineField(new EntityField("AmountForums", + new ScalarQueryExpression(ForumFields.ForumID.SetAggregateFunction(AggregateFunction.Count), + (ForumFields.SectionID == SectionFields.SectionID))), 4); + + // Sort sections alphabitacally + SortExpression sorter = new SortExpression(SectionFields.OrderNo | SortOperator.Ascending); + sorter.Add(SectionFields.SectionName | SortOperator.Ascending); + + IPredicate filter = null; + if(excludeEmptySections) + { + // filter on sections which don't have a forum + filter = ((EntityField)fields[4] != 0); + } + + TypedListDAO dao = new TypedListDAO(); + DataTable results = new DataTable(); + dao.GetMultiAsDataTable(fields, results, 0, sorter, filter, null, true, null, null, 0, 0); + return results.DefaultView; + } + + + /// + /// Gets all sections. + /// + /// SectionCollection + public static SectionCollection GetAllSections() + { + // Sort sections on orderno first then on name alphabetically + SortExpression sorter = new SortExpression(SectionFields.OrderNo | SortOperator.Ascending); + sorter.Add(SectionFields.SectionName | SortOperator.Ascending); + + SectionCollection sections = new SectionCollection(); + //Retrieves all Entity objects into this Collection object. + sections.GetMulti(null, 0, sorter); + + return sections; + } + + + /// + /// Gets the section entity of the id passed in + /// + /// The section ID. + /// loaded sectionentity or null if not found + public static SectionEntity GetSection(int sectionID) + { + SectionEntity toReturn = new SectionEntity(sectionID); + if(toReturn.IsNew) + { + // not found + return null; + } + return toReturn; + } + } +} diff --git a/BL/SectionManager.cs b/BL/SectionManager.cs new file mode 100644 index 0000000..1081cdd --- /dev/null +++ b/BL/SectionManager.cs @@ -0,0 +1,118 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; + +namespace SD.HnD.BL +{ + /// + /// General class for Section management tasks. + /// + public static class SectionManager + { + /// + /// Adds a new section to the forum system. + /// + /// The name. + /// The description. + /// The order no for the section. Sections are sorted ascending on orderno. + /// + /// the SectionID of the new section. Or Zero if failed + /// + public static int AddNewSection(string name, string description, short orderNo) + { + SectionEntity section = new SectionEntity(); + + // fill the entity fields with data + section.SectionName = name; + section.SectionDescription = description; + section.OrderNo = orderNo; + + // try to save the entity + bool saveResult = section.Save(); + + // if succeeds return the new ID, else return Zero. + if(saveResult == true) + { + return section.SectionID; + } + else + { + return 0; + } + } + + + /// + /// Modifies the given section's name and description + /// + /// ID of section to modify + /// New name of section + /// Description of section + /// The order no for the section. Sections are sorted ascending on orderno. + /// True if succeeded, false otherwise + public static bool ModifySection(int ID, string name, string description, short orderNo) + { + // load the entity from the database + SectionEntity section = new SectionEntity(ID); + + //check if the entity is new (not found in the database), then return false. + if(section.IsNew == true) + { + return false; + } + + // update the fields with new values + section.SectionName = name; + section.SectionDescription = description; + section.OrderNo = orderNo; + + //try to save the changes + return section.Save(); + } + + + /// + /// Removes the given section from the database. Returns true if succeeded. + /// + /// ID of section to delete + /// True if succeeded, false otherwise + public static bool DeleteSection(int ID) + { + // trying to delete the entity directly from the database without first loading it. + // for that we use an entity collection and use the DeleteMulti method with a filter on the PK. + PredicateExpression deleteFilter = new PredicateExpression(); + deleteFilter.Add(SectionFields.SectionID == ID); + + SectionCollection sections = new SectionCollection(); + // try to delete the entity + int deletedRows = sections.DeleteMulti(deleteFilter); + + // there should only be one deleted row, since we are filtering by the PK. + // return true if there's 1, otherwise false. + return (deletedRows == 1); + } + + } +} diff --git a/BL/SecurityGuiHelper.cs b/BL/SecurityGuiHelper.cs new file mode 100644 index 0000000..ecf142f --- /dev/null +++ b/BL/SecurityGuiHelper.cs @@ -0,0 +1,370 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Text; +using System.Collections; + +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.EntityClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.DaoClasses; +using System.Collections.Generic; + +namespace SD.HnD.BL +{ + /// + /// Class to provide essential data for the Security Gui. + /// + public static class SecurityGuiHelper + { + /// + /// Gets all role objects. + /// + /// + public static RoleCollection GetAllRoles() + { + RoleCollection toReturn = new RoleCollection(); + toReturn.GetMulti(null, 0, new SortExpression(RoleFields.RoleDescription | SortOperator.Ascending)); + return toReturn; + } + + /// + /// Gets all audit actions. + /// + /// + public static AuditActionCollection GetAllAuditActions() + { + AuditActionCollection toReturn = new AuditActionCollection(); + toReturn.GetMulti(null, 0, new SortExpression(AuditActionFields.AuditActionDescription | SortOperator.Ascending)); + return toReturn; + } + + + /// + /// Gets all audit actions for role. + /// + /// Role ID. + /// + public static RoleAuditActionCollection GetAllAuditActionsForRole(int roleID) + { + RoleAuditActionCollection toReturn = new RoleAuditActionCollection(); + toReturn.GetMulti((RoleAuditActionFields.RoleID == roleID)); + return toReturn; + } + + + /// + /// Gets all audits for user. + /// + /// User ID. + /// All audit data objects (polymorphic) + public static AuditDataCoreCollection GetAllAuditsForUser(int userID) + { + AuditDataCoreCollection toReturn = new AuditDataCoreCollection(); + // setup polymorphic prefetch paths: + PrefetchPath path = new PrefetchPath((int)EntityType.AuditDataCoreEntity); + path.Add(AuditDataMessageRelatedEntity.PrefetchPathMessage).SubPath.Add(MessageEntity.PrefetchPathThread); + path.Add(AuditDataThreadRelatedEntity.PrefetchPathThread); + toReturn.GetMulti((AuditDataCoreFields.UserID == userID), + 50, new SortExpression(AuditDataCoreFields.AuditedOn | SortOperator.Descending), null, path); + return toReturn; + } + + + /// + /// Gets all IP ban entities, sorted by range for the page specified. + /// + /// The page number for the page to read. Specify 0 to fetch all ip bans. + /// Size of the page to fetch. Specify 0 to fetch all ip bans. + /// If set to true, it will prefetch the user entity into the ipBan entity, for the user who set the IPBan + /// + /// the collection of ipban entities requested + /// + public static IPBanCollection GetAllIPBans(int pageNo, int pageSize, bool prefetchUser) + { + IPBanCollection toReturn = new IPBanCollection(); + PrefetchPath path = null; + if(prefetchUser) + { + // build the Prefetch path to fetch the user as well + path = new PrefetchPath((int)EntityType.IPBanEntity); + path.Add(IPBanEntity.PrefetchPathSetByUser); + } + toReturn.GetMulti(null, 0, new SortExpression(IPBanFields.Range | SortOperator.Ascending), null, path, pageNo, pageSize); + return toReturn; + } + + + /// + /// Gets the total IP ban count as they're stored in the DB now. + /// + /// the # of IPBans stored in the database. + public static int GetTotalIPBanCount() + { + IPBanCollection toReturn = new IPBanCollection(); + return toReturn.GetDbCount(); + } + + + /// + /// Constructs a dataview with all the roles available, complete with statistics (#users, if the role is used as anonymous role or default user role) + /// + /// DataView with all the Roles available, directly bindable to webcontrols + public static DataView GetAllRolesWithStatisticsAsDataView() + { + // create dynamic list, with all fields of Role and 3 extra fields: one field for the # of users in the role, one field which + // signals if the role is the defaultnewuserrole and one field which signals if the role is the anonymous role. The # of users field is + // used in the query, the other two fields are added later for efficiency. + ResultsetFields fields = new ResultsetFields((int)RoleFieldIndex.AmountOfFields + 1); + fields.DefineField(RoleFields.RoleID, 0); + fields.DefineField(RoleFields.RoleDescription, 1); + // now add the # of users subquery to the resultset. This will result in the query: + // ( + // SELECT COUNT(UserID) + // FROM RoleUser + // WHERE RoleUser.RoleID = Role.RoleID + // ) AS AmountUsersInRole + fields.DefineField(new EntityField("AmountUsersInRole", + new ScalarQueryExpression(RoleUserFields.UserID.SetAggregateFunction(AggregateFunction.Count), + (RoleUserFields.RoleID == RoleFields.RoleID))), 2); + + // fetch the data into a datatable. + DataTable results = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + dao.GetMultiAsDataTable(fields, results, 0, new SortExpression( RoleFields.RoleDescription | SortOperator.Ascending ), + null, null, true, null, null, 0, 0); + + // we now fetch the system data which contains the two role id's we've to check with in the results to return. + SystemDataEntity systemData = SystemGuiHelper.GetSystemSettings(); + // now add 2 columns to the datatable, booleans, which are used to store the flags for IsDefaultNewUserRole and IsAnonymousRole, so the complete + // set of data can be processed in a list form. + results.Columns.Add(new DataColumn("IsDefaultNewUserRole", typeof(bool))); + results.Columns.Add(new DataColumn("IsAnonymousRole", typeof(bool))); + foreach(DataRow row in results.Rows) + { + row["IsDefaultNewUserRole"] = ((int)row["RoleID"] == systemData.DefaultRoleNewUser); + row["IsAnonymousRole"] = ((int)row["RoleID"] == systemData.AnonymousRole); + } + + // done, return the dataview of this datatable + return results.DefaultView; + } + + + /// + /// Gets the RoleEntity with the id specified. + /// + /// Role to retrieve + /// Entity with the role data or null if not found + public static RoleEntity GetRole(int roleID) + { + RoleEntity toReturn = new RoleEntity( roleID ); + if(toReturn.IsNew) + { + return null; + } + return toReturn; + } + + + /// + /// Retrieves an entitycollection with all the systemactionright-role combinations currently defined for the role specified + /// + /// The role which system action rights should be retrieved. + /// filled collection with entities of type RoleSystemActionRightEntity + public static RoleSystemActionRightCollection GetSystemActionRightRolesForRole(int roleID) + { + RoleSystemActionRightCollection toReturn = new RoleSystemActionRightCollection(); + toReturn.GetMulti((RoleSystemActionRightFields.RoleID == roleID)); + return toReturn; + } + + + /// + /// Retrieves an entitycollection with all the forum-actionright-role combinations currently defined for the role specified for the given forum + /// + /// The role which forum action rights should be retrieved. + /// The forum ID. + /// filled entity collection + /// + public static ForumRoleForumActionRightCollection GetForumActionRightRolesFoForumRole(int roleID, int forumID) + { + ForumRoleForumActionRightCollection toReturn = new ForumRoleForumActionRightCollection(); + PredicateExpression filter = new PredicateExpression(ForumRoleForumActionRightFields.RoleID == roleID); + filter.AddWithAnd((ForumRoleForumActionRightFields.ForumID==forumID)); + toReturn.GetMulti(filter); + return toReturn; + } + + + /// + /// Retrieves all ActionRight entities which are applyable to a forum. + /// + /// entitycollection with all the action rights requested + public static ActionRightCollection GetAllActionRightsApplybleToAForum() + { + ActionRightCollection toReturn = new ActionRightCollection(); + toReturn.GetMulti((ActionRightFields.AppliesToForum == true), 0, new SortExpression( ActionRightFields.ActionRightID | SortOperator.Ascending ) ); + return toReturn; + } + + + /// + /// Retrieves all action rights which are system action rights and which aren't applyable to a forum + /// + /// entitycollection with all the system action rights + public static ActionRightCollection GetAllSystemActionRights() + { + ActionRightCollection toReturn = new ActionRightCollection(); + toReturn.GetMulti((ActionRightFields.AppliesToSystem == true), 0, new SortExpression(ActionRightFields.ActionRightID | SortOperator.Ascending)); + return toReturn; + } + + + /// + /// Gets the system action rights for user. + /// + /// The user ID. + /// The action rights to be returned. + /// filled collection + public static ActionRightCollection GetSystemActionRightsForUser(int userID) + { + ActionRightCollection actionRights = new ActionRightCollection(); + + // the subquery in the filter requires joins as the filter's subquery has to filter on fields in related entities: + // WHERE ActionRightID IN (SELECT ActionRightID FROM RoleSystemActionRight INNER JOIN Role ... INNER JOIN RoleUser ... WHERE RoleUser.UserID=userID) + RelationCollection relations = new RelationCollection(); + relations.Add(RoleSystemActionRightEntity.Relations.RoleEntityUsingRoleID); + relations.Add(RoleEntity.Relations.RoleUserEntityUsingRoleID); + + PredicateExpression filter = new PredicateExpression(); + // retrieve system action rights only. + filter.Add(ActionRightFields.AppliesToSystem == true); + filter.Add(new FieldCompareSetPredicate( + ActionRightFields.ActionRightID, + RoleSystemActionRightFields.ActionRightID, + SetOperator.In, + (RoleUserFields.UserID == userID), relations)); + + actionRights.GetMulti(filter); + return actionRights; + } + + + /// + /// Gets the Forum action rights for user. + /// + /// The user ID. + /// fetched collection + public static ForumRoleForumActionRightCollection GetForumsActionRightsForUser(int userID) + { + ForumRoleForumActionRightCollection forumRoleActionRights = new ForumRoleForumActionRightCollection(); + + // the subquery in the filter requires joins as the filter's subquery has to filter on fields in related entities: + // WHERE RoleID IN (SELECT RoleID FROM Role INNER JOIN RoleUser ... WHERE RoleUser.UserID=userID) + RelationCollection relations = new RelationCollection(); + relations.Add(RoleEntity.Relations.RoleUserEntityUsingRoleID); + + PredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareSetPredicate(ForumRoleForumActionRightFields.RoleID, + RoleFields.RoleID, SetOperator.In, (RoleUserFields.UserID == userID), relations)); + + forumRoleActionRights.GetMulti(filter); + return forumRoleActionRights; + } + + + /// + /// Gets the audit actions for user. + /// + /// The user ID. + /// fetched collection + public static AuditActionCollection GetAuditActionsForUser(int userID) + { + AuditActionCollection auditActions = new AuditActionCollection(); + + // the subquery in the filter requires joins as the filter's subquery has to filter on fields in related entities: + // WHERE AuditActionID IN (SELECT AuditActionID FROM RoleAuditAction INNER JOIN Role ... INNER JOIN RoleUser ... WHERE RoleUser.UserID=userID) + RelationCollection relations = new RelationCollection(); + relations.Add(RoleAuditActionEntity.Relations.RoleEntityUsingRoleID); + relations.Add(RoleEntity.Relations.RoleUserEntityUsingRoleID); + + relations.Add(new EntityRelation(RoleAuditActionFields.RoleID, RoleUserFields.RoleID, RelationType.ManyToMany)); + + PredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareSetPredicate(AuditActionFields.AuditActionID, + RoleAuditActionFields.AuditActionID, + SetOperator.In, + (RoleUserFields.UserID == userID), relations)); + auditActions.GetMulti(filter); + return auditActions; + } + + + /// + /// Checks if passed in IP address, in string format matches an IP ban. If the ip address matches an ip ban, the matching IP ban is returned + /// + /// All cached IP bans from the cache. + /// The ip address of the user, in string format. + /// null if the user doesn't match any IP ban, or the first IPBan entity it matches + public static IPBanEntity GetIPBanMatchingUserIPAddress(Dictionary> allCachedIPBans, string ipAddressUser) + { + string[] ipAddressSegments = ipAddressUser.Split('.'); + if(ipAddressSegments.Length != 4) + { + // can't do matching as the ip address has less or more segments + return null; + } + + Dictionary rangeBans = null; + StringBuilder ipTemp = new StringBuilder(); + IPBanEntity toReturn = null; + + // for each segment we'll check if it, combined with the previous segments, results in a match. If not, the next segment will be tried. + for(int i=0;i<4;i++) + { + // check range ban. Build ip address segments from ip address passed in and check that with the segments in the range ban dictionary + if(i > 0) + { + ipTemp.Append("."); + } + ipTemp.Append(ipAddressSegments[i]); + + allCachedIPBans.TryGetValue(8*(i+1), out rangeBans); + if(rangeBans==null) + { + // no range bans with this range, continue + continue; + } + + if(rangeBans.TryGetValue(ipTemp.ToString(), out toReturn)) + { + // we have a match! + break; + } + } + + return toReturn; + } + } +} diff --git a/BL/SecurityManager.cs b/BL/SecurityManager.cs new file mode 100644 index 0000000..a0fdb0d --- /dev/null +++ b/BL/SecurityManager.cs @@ -0,0 +1,609 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Collections; +using System.Security.Cryptography; + +using SD.HnD.Utility; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using System.Collections.Generic; + +namespace SD.HnD.BL +{ + /// + /// General class which manages the security in the System. + /// + public static class SecurityManager + { + #region Enums + /// + /// Standard enum which is used to signal back the authentication result of an authentication request. + /// + public enum AuthenticateResult:int + { + /// + /// Authentication was succesful + /// + AllOk, + /// + /// Authentication wasn't succesful, the combination of username and password was wrong. + /// + WrongUsernamePassword, + /// + /// The user couldn't be authenticated because the user is currently banned. + /// + IsBanned + } + #endregion + + /// + /// Audits the login of the user with the id specified. + /// + /// User ID. + /// true if the save was successful, false otherwise + public static bool AuditLogin(int userID) + { + AuditDataCoreEntity toLog = new AuditDataCoreEntity(); + toLog.AuditActionID = (int)AuditActions.AuditLogin; + toLog.UserID = userID; + toLog.AuditedOn = DateTime.Now; + return toLog.Save(); + } + + + /// + /// Audits the creation of a new thread by the specified user + /// + /// User ID. + /// Thread ID. + /// true if the save was successful, false otherwise + public static bool AuditNewThread(int userID, int threadID) + { + AuditDataThreadRelatedEntity toLog = new AuditDataThreadRelatedEntity(); + toLog.AuditActionID = (int)AuditActions.AuditNewThread; + toLog.UserID = userID; + toLog.AuditedOn = DateTime.Now; + toLog.ThreadID = threadID; + return toLog.Save(); + } + + + /// + /// Audits the edit of the memo field for a thread by the specified user + /// + /// User ID. + /// Thread ID. + /// true if the save was successful, false otherwise + public static bool AuditEditMemo(int userID, int threadID) + { + AuditDataThreadRelatedEntity toLog = new AuditDataThreadRelatedEntity(); + toLog.AuditActionID = (int)AuditActions.AuditEditMemo; + toLog.UserID = userID; + toLog.AuditedOn = DateTime.Now; + toLog.ThreadID = threadID; + return toLog.Save(); + } + + + /// + /// Audits the approval of an attachment. We'll log the approval of an attachment with the messageid, as attachments are stored related to a message. + /// + /// The user ID. + /// The attachment ID. + public static bool AuditApproveAttachment(int userID, int attachmentID) + { + AuditDataMessageRelatedEntity toLog = new AuditDataMessageRelatedEntity(); + + AttachmentCollection collection = new AttachmentCollection(); + // use a scalar query to obtain the message id so we don't have to pull it completely in memory. An attachment can be big in size so we don't want to + // read the entity to just read the messageid. We could use excluding fields to avoid the actual attachment data, but this query is really simple. + // this query will return 1 value directly from the DB, so it won't read all attachments first into memory. + int messageID = (int)collection.GetScalar(AttachmentFieldIndex.MessageID, null, AggregateFunction.None, (AttachmentFields.AttachmentID==attachmentID)); + toLog.AuditActionID = (int)AuditActions.AuditApproveAttachment; + toLog.UserID = userID; + toLog.MessageID = messageID; + toLog.AuditedOn = DateTime.Now; + return toLog.Save(); + } + + + /// + /// Audits the creation of a new message by the specified user + /// + /// User ID. + /// Message ID. + /// true if the save was successful, false otherwise + public static bool AuditNewMessage(int userID, int messageID) + { + AuditDataMessageRelatedEntity toLog = new AuditDataMessageRelatedEntity(); + toLog.AuditActionID = (int)AuditActions.AuditNewMessage; + toLog.UserID = userID; + toLog.AuditedOn = DateTime.Now; + toLog.MessageID = messageID; + return toLog.Save(); + } + + + /// + /// Audits the alternation of a message by the specified user + /// + /// User ID. + /// Message ID. + /// + public static bool AuditAlteredMessage(int userID, int messageID) + { + AuditDataMessageRelatedEntity toLog = new AuditDataMessageRelatedEntity(); + toLog.AuditActionID = (int)AuditActions.AuditAlteredMessage; + toLog.UserID = userID; + toLog.AuditedOn = DateTime.Now; + toLog.MessageID = messageID; + return toLog.Save(); + } + + + /// + /// Persists the IP ban unit of work passed into this method. The call to this method originates from the form which manages IP bans with + /// one LLBLGenProDataSource controls which is used to persist changes. This LLBLGenProDataSource produces a UnitOfWork when the + /// PerformWork event is raised and this UoW contains the changes to persist. This routine persists these changes. + /// + /// The unitofwork object which contains 1 or more changes (with standard .NET controls, this is 1) to persist. + public static void PersistIPBanUnitOfWork(UnitOfWork uow) + { + // pass a new transaction to the commit routine and auto-commit this transaction when the transaction is complete. + uow.Commit(new Transaction(IsolationLevel.ReadCommitted, "PersistIPBans"), true); + } + + + /// + /// Creates a new Role in the system. If the user specified a role description that is already available, the unique constraint violation will be + /// caught and 0 is returned in that case. + /// + /// Description to store + /// new RoleID if succeeded. If the description was already available, 0 is returned + public static int CreateNewRole(string roleDescription) + { + if(CheckIfRoleDescriptionIsPresent(roleDescription)) + { + // is already present + return 0; + } + + RoleEntity newRole = new RoleEntity(); + newRole.RoleDescription = roleDescription; + + int toReturn = 0; + bool result = newRole.Save(); + if(result) + { + // save was succesful, read back the ID that was just created so we can return that to the caller. + toReturn = newRole.RoleID; + } + return toReturn; + } + + + /// + /// Modifies the given role: it resets the system action rights for the given role to the given set of action rights and it modifies + /// the role description for the given role. If the user specified a role description that is already available, false will be returned to signal + /// that the save failed. + /// + /// The action rights. + /// The role ID. + /// The role description. + /// true if succeeded, false otherwise + public static bool ModifyRole(List actionRightIDs, int roleID, string roleDescription) + { + // read the existing role entity from the database. + RoleEntity roleToModify = new RoleEntity(roleID); + if(roleToModify.IsNew) + { + // not found + return false; + } + + // check if the description is different. If so, we've to check if the new roledescription is already present. If so, we'll + // abort the save + if(roleToModify.RoleDescription != roleDescription) + { + if(CheckIfRoleDescriptionIsPresent(roleDescription)) + { + // new description, is already present, fail + return false; + } + } + + // all set. We're going to delete all Role - SystemAction Rights combinations first, as we're going to re-insert them later on. + // We'll use a transaction to be able to roll back all our changes if something fails. + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "ModifyRole"); + try + { + RoleSystemActionRightCollection roleActionRights = new RoleSystemActionRightCollection(); + // add this collection to the transaction so all actions executed through this collection will be inside the transaction + trans.Add(roleActionRights); + // delete all role-systemactionright combinations directly from the database, by issuing a direct delete on the database, using a filter + // on roleid + roleActionRights.DeleteMulti((RoleSystemActionRightFields.RoleID == roleID)); + + // add new role-systemactionright entities which we'll save to the database after that + foreach(int actionRightID in actionRightIDs) + { + RoleSystemActionRightEntity toAdd = new RoleSystemActionRightEntity(); + toAdd.ActionRightID = actionRightID; + toAdd.RoleID = roleID; + roleActionRights.Add(toAdd); + } + // save the new entities to the database + roleActionRights.SaveMulti(); + + // we'll now save the role and the role description, if it's changed. Otherwise the save action will be a no-op. + // add it to the transaction + trans.Add(roleToModify); + roleToModify.RoleDescription = roleDescription; + roleToModify.Save(); + + // all done, commit the transaction + trans.Commit(); + return true; + } + catch + { + // failed, roll back transaction. + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Saves the audit actions for role specified. First removes all present rows for the roleid + /// + /// Audit action IDs. + /// Role ID. + /// true if the save action succeeded, false otherwise + public static bool SaveAuditActionsForRole(List auditActionIDs, int roleID) + { + RoleAuditActionCollection roleAuditActions = new RoleAuditActionCollection(); + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "SaveAuditActionsForRole"); + + // add this collection to the transaction so all actions executed through this collection will be inside the transaction + trans.Add(roleAuditActions); + + try + { + // first remove the existing rows for the role + roleAuditActions.DeleteMulti((RoleAuditActionFields.RoleID == roleID)); + + // THEN add new ones to the same collection. + foreach(int auditActionID in auditActionIDs) + { + RoleAuditActionEntity newRoleAuditAction = new RoleAuditActionEntity(); + newRoleAuditAction.AuditActionID = auditActionID; + newRoleAuditAction.RoleID = roleID; + roleAuditActions.Add(newRoleAuditAction); + } + + // save all new entities + roleAuditActions.SaveMulti(); + + // succeeded, commit transaction + trans.Commit(); + return true; + } + catch + { + // failed, rollback transaction + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Saves the given set of actionrights as the set of forum action rights for the given forum / role combination. + /// It first removes all current action rights for that combination. + /// + /// List of actionrights to set of this role + /// Role to use + /// Forum to use + /// true if succeeded, false otherwise + public static bool SaveForumActionRightsForForumRole(List actionRightIDs, int roleID, int forumID) + { + ForumRoleForumActionRightCollection forumRightsPerRole = new ForumRoleForumActionRightCollection(); + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "SaveForumActionRights"); + + // add this collection to the transaction so all actions executed through this collection will be inside the transaction + trans.Add(forumRightsPerRole); + try + { + // first remove the existing rows for the role + forumRightsPerRole.DeleteMulti((ForumRoleForumActionRightFields.RoleID == roleID) & (ForumRoleForumActionRightFields.ForumID == forumID)); + + // THEN add new ones + foreach(int actionRightID in actionRightIDs) + { + ForumRoleForumActionRightEntity newForumRightPerRole = new ForumRoleForumActionRightEntity(); + newForumRightPerRole.ActionRightID = actionRightID; + newForumRightPerRole.ForumID = forumID; + newForumRightPerRole.RoleID = roleID; + forumRightsPerRole.Add(newForumRightPerRole); + } + + // save the new entities + forumRightsPerRole.SaveMulti(); + + // all done, commit transaction + trans.Commit(); + return true; + } + catch + { + // failed, rollback transaction + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Adds all users which ID's are stored in UsersToAdd, to the role with ID RoleID. + /// + /// List with UserIDs of the users to add + /// ID of role the users will be added to + /// true if succeeded, false otherwise + public static bool AddUsersToRole(List userIDsToAdd, int roleID) + { + if(userIDsToAdd.Count<=0) + { + return true; + } + + RoleUserCollection roleUsers = new RoleUserCollection(); + // for each userid in the list, add a new entity to the collection + foreach(int userID in userIDsToAdd) + { + RoleUserEntity newRoleUser = new RoleUserEntity(); + newRoleUser.UserID = userID; + newRoleUser.RoleID = roleID; + roleUsers.Add(newRoleUser); + } + + // save the new role-user combinations + return (roleUsers.SaveMulti() > 0); + } + + + /// + /// Removes all users which ID's are stored in UsersToRemove, from the role with ID RoleID. + /// + /// ArrayList with UserIDs of the users to Remove + /// ID of role the users will be removed from + /// true if succeeded, false otherwise + public static bool RemoveUsersFromRole(List userIDsToRemove, int roleID) + { + if(userIDsToRemove.Count<=0) + { + return true; + } + + // we'll delete all role-user combinations for the users in the given range plus for the given role. + // if there's just one user, we'll use an optimization, as the range query will result in an IN (param, param... ) query, + // and an field IN (param) query, is much slower compared to field = param, at least on Sqlserver. + + // produce the filter which will be used to filter out the entities to delete. + PredicateExpression filter = new PredicateExpression(); + if(userIDsToRemove.Count == 1) + { + // use compare value predicate instead + filter.Add((RoleUserFields.UserID == userIDsToRemove[0])); + } + else + { + // add a range filter + filter.Add((RoleUserFields.UserID == userIDsToRemove)); + } + // add the filter for the role as with AND. + filter.AddWithAnd((RoleUserFields.RoleID == roleID)); + + // delete the entities directly from the database. As this gives a single DELETE statement, we don't have to start a transaction manually. + RoleUserCollection roleUsers = new RoleUserCollection(); + return (roleUsers.DeleteMulti(filter) > 0); + } + + + /// + /// Deletes the given role from the system. + /// + /// ID of role to delete + /// true if succeeded, false otherwise + public static bool DeleteRole(int roleID) + { + RoleEntity toDelete = SecurityGuiHelper.GetRole(roleID); + if(toDelete == null) + { + // not found + return false; + } + + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "DeleteRole"); + + try + { + // remove the role - forum - action right entities + ForumRoleForumActionRightCollection forumRoleActionRights = new ForumRoleForumActionRightCollection(); + trans.Add(forumRoleActionRights); + forumRoleActionRights.DeleteMulti(ForumRoleForumActionRightFields.RoleID == roleID); + + // Remove role-audit action entities + RoleAuditActionCollection roleAuditActions = new RoleAuditActionCollection(); + trans.Add(roleAuditActions); + roleAuditActions.DeleteMulti(RoleAuditActionFields.RoleID == roleID); + + // remove Role - systemright entities + RoleSystemActionRightCollection roleSystemRights = new RoleSystemActionRightCollection(); + trans.Add(roleSystemRights); + roleSystemRights.DeleteMulti(RoleSystemActionRightFields.RoleID == roleID); + + // remove Role - user entities + RoleUserCollection roleUsers = new RoleUserCollection(); + trans.Add(roleUsers); + roleUsers.DeleteMulti(RoleUserFields.RoleID == roleID); + + // delete the actual role + trans.Add(toDelete); + toDelete.Delete(); + trans.Commit(); + return true; + } + catch + { + // error occured, rollback + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Checks if the user with the given NickName exists in the database. This is necessary to check if a user which gets authenticated through + /// forms authentication is still available in the database. + /// + /// The nickname of the user to check if he/she exists in the database + /// true if user exists, false otherwise. + public static bool DoesUserExist(string nickName) + { + UserEntity user = new UserEntity(); + // fetch the user using the unique constraint functionality. + return user.FetchUsingUCNickName(nickName); + } + + + /// + /// Checks if the user with the given UserID exists in the database. + /// + /// The UserID of the user to check if he/she exists in the database + /// true if user exists, false otherwise. + public static bool DoesUserExist(int userID) + { + UserEntity user = new UserEntity(userID); + // return true if the user entity was fetched succesfully, i.e.: the entity isn't new anymore. + return (!user.IsNew); + } + + + /// + /// Checks if the user with the given NickName exists in the database. This is necessary to check if a user which gets authenticated through + /// forms authentication is still available in the database. + /// + /// The nickname of the user to check if he/she exists in the database + /// The user object is returned + /// true if user exists, false otherwise. + public static bool DoesUserExist(string nickName, out UserEntity user) + { + user = new UserEntity(); + // fetch the user using the unique constraint functionality. + return user.FetchUsingUCNickName(nickName); + } + + + /// + /// Authenticates the user with the given Nickname and the given Password. + /// + /// Nickname of the user + /// Password of the user + /// AuthenticateResult.AllOk if the user could be authenticated, + /// AuthenticateResult.WrongUsernamePassword if user couldn't be authenticated given the current credentials, + /// AuthenticateResult.IsBanned if the user is banned. + public static AuthenticateResult AuthenticateUser(string nickName, string password, out UserEntity user) + { + // fetch the Roles related to the user when fetching the user, using a prefetchPath object. + PrefetchPath prefetchPath = new PrefetchPath((int)EntityType.UserEntity); + prefetchPath.Add(UserEntity.PrefetchPathRoles); + + // fetch the user data using the nickname which has a unique constraint + user = new UserEntity(); + bool fetchResult = user.FetchUsingUCNickName(nickName, prefetchPath); + + if(!fetchResult) + { + // not found. Simply return that the user has specified a wrong username/password combination. + return AuthenticateResult.WrongUsernamePassword; + } + + // user was found, check if the user can be authenticated and has specified the correct password. + if(user.IsBanned) + { + // user is banned. We'll report that to the caller + return AuthenticateResult.IsBanned; + } + else + { + // check password and UserID. We disallow the user with id 0 to login as that's the anonymous coward ID for a user not logged in. + string md5HashedPassword = HnDGeneralUtils.CreateMD5HashedBase64String(password); + if((md5HashedPassword == user.Password)&&(user.UserID != Globals.UserIDToDenyLogin)) + { + // correct username/password combination + return AuthenticateResult.AllOk; + } + else + { + // something was wrong, report wrong authentication combination + return AuthenticateResult.WrongUsernamePassword; + } + } + } + + + /// + /// Checks if the specified role description is already present. + /// + /// The role description. + /// true if the role description is already present, otherwise false. + private static bool CheckIfRoleDescriptionIsPresent(string roleDescription) + { + // check if the role description is already available. Do that by performing a GetDbCount query on the role entities using a filter for the description. + RoleCollection roles = new RoleCollection(); + // perform the getdbcount query. + int count = roles.GetDbCount((RoleFields.RoleDescription == roleDescription)); + return (count > 0); + } + } +} diff --git a/BL/SupportQueueGuiHelper.cs b/BL/SupportQueueGuiHelper.cs new file mode 100644 index 0000000..088b689 --- /dev/null +++ b/BL/SupportQueueGuiHelper.cs @@ -0,0 +1,235 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections.Generic; +using System.Text; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.HelperClasses; +using System.Data; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL; + +namespace SD.HnD.BL +{ + /// + /// Class to provide essential data for the Support queue gui. + /// + public static class SupportQueueGuiHelper + { + /// + /// Gets the support queue entity with the queue id passed in + /// + /// The queue ID. + /// the supportqueue entity requested or null if not found. + public static SupportQueueEntity GetSupportQueue(int queueID) + { + // fetch using the constructor. + SupportQueueEntity toReturn = new SupportQueueEntity(queueID); + if(toReturn.IsNew) + { + // not found + return null; + } + return toReturn; + } + + + /// + /// Gets all support queues known in the system, sorted by orderno, ascending. + /// + /// filled collection with entities requested. + public static SupportQueueCollection GetAllSupportQueues() + { + SupportQueueCollection toReturn = new SupportQueueCollection(); + // fetch all supportqueue entities and sort on the orderno fields + toReturn.GetMulti(null, 0, new SortExpression(SupportQueueFields.OrderNo | SortOperator.Ascending)); + return toReturn; + } + + + /// + /// Gets the support queue of the thread with the threadID specified. + /// + /// The thread ID. + /// The requested supportqueue entity, or null if the thread isn't in a support queue. + public static SupportQueueEntity GetQueueOfThread(int threadID) + { + return GetQueueOfThread(threadID, null); + } + + + /// + /// Gets the support queue of the thread with the threadID specified. + /// + /// The thread ID. + /// The transaction currently in progress. Can be null if no transaction is in progress. + /// + /// The requested supportqueue entity, or null if the thread isn't in a support queue. + /// + public static SupportQueueEntity GetQueueOfThread(int threadID, Transaction trans) + { + // the relation supportqueue - thread is stored in a SupportQueueThread entity. Use that entity as a filter for the support queue. If + // that entity doesn't exist, the thread isn't in a supportqueue. + + RelationCollection relations = new RelationCollection(); + relations.Add(SupportQueueEntity.Relations.SupportQueueThreadEntityUsingQueueID); + + // use a supportqueue collection to fetch the support queue, which will contain 0 or 1 entities after the fetch + SupportQueueCollection supportQueues = new SupportQueueCollection(); + // if a transaction has been specified, we've to add the collection to the transaction so the fetch takes place inside the same transaction so no + // deadlocks occur on sqlserver + if(trans != null) + { + trans.Add(supportQueues); + } + + // fetch using a filter on a related entity, namely the SupportQueueThread entity. We'll filter on thread. + supportQueues.GetMulti((SupportQueueThreadFields.ThreadID == threadID), relations); + if(supportQueues.Count > 0) + { + // in a queue, return the instance + return supportQueues[0]; + } + else + { + // not in a queue, return null + return null; + } + } + + + /// + /// Gets the support queue thread info entity and if specified, prefetches the user entity which claimed the related thread. + /// + /// The thread ID. + /// if set to true it will + /// fetched entity if found, otherwise null + public static SupportQueueThreadEntity GetSupportQueueThreadInfo(int threadID, bool prefetchClaimUser) + { + SupportQueueThreadEntity toReturn = new SupportQueueThreadEntity(); + PrefetchPath path = null; + if(prefetchClaimUser) + { + // prefetch the user who claimed this thread (if any) + path = new PrefetchPath((int)EntityType.SupportQueueThreadEntity); + path.Add(SupportQueueThreadEntity.PrefetchPathClaimedByUser); + } + + // now fetch the entity using the unique constraint on Thread by specifying the threadID passed in. Also specify the prefetch path (if any) + toReturn.FetchUsingUCThreadID(threadID, path); + if(toReturn.IsNew) + { + // not found + return null; + } + return toReturn; + } + + + /// + /// Gets the threads and accompanying statistics info, in the supportqueue specified. Only the threads which are in the forums in the list of + /// accessable forums are returned. + /// + /// A list of accessable forums IDs, which the user has permission to access. + /// The ID of the support queue to retrieve the threads for. + /// a dataView of Active threads + public static DataView GetAllThreadsInSupportQueueAsDataView(List accessableForums, int supportQueueID) + { + // return null, if the user does not have a valid list of forums to access + if(accessableForums == null || accessableForums.Count <= 0) + { + return null; + } + + PredicateExpression filter = new PredicateExpression(); + // only the forums the user has access to + filter.Add(ThreadFields.ForumID == accessableForums); + // only the threads which are in this queue. + filter.Add(SupportQueueThreadFields.QueueID == supportQueueID); + + SortExpression sorter = new SortExpression(ThreadFields.ThreadLastPostingDate | SortOperator.Ascending); + + // We'll use a dynamic list to retrieve all threads which are in support queues + ResultsetFields fields = ThreadGuiHelper.BuildDynamicListForAllThreadsWithStats(); + int count = fields.Count; + // add fields to the resultset fields as we need data from forum, the nickname of the user who placed the thread in the queue, + // the nickname of the user who claimed the thread (if any) and the date/times when the thread was placed or claimed + fields.Expand(7); + fields.DefineField(ForumFields.ForumName, count); + fields.DefineField(UserFields.NickName, count + 1, "NickNamePlacedInQueue", "PlacedInQueueUser"); + fields.DefineField(SupportQueueThreadFields.PlacedInQueueByUserID, count + 2); + fields.DefineField(SupportQueueThreadFields.PlacedInQueueOn, count + 3); + fields.DefineField(UserFields.NickName, count + 4, "NickNameClaimedThread", "ClaimedThreadUser"); + fields.DefineField(SupportQueueThreadFields.ClaimedByUserID, count + 5); + fields.DefineField(SupportQueueThreadFields.ClaimedOn, count + 6); + + // now build the relations for the dynamic list. We'll join User three times: once for the startuser, once for the lastpost user and + // once for the user who placed the thread in the queue. + // Also, we'll join the last message to the thread. The last message is joined with a custom filter added to the relation. + RelationCollection relations = ThreadGuiHelper.BuildRelationsForAllThreadsWithStats(); + + // add the relation thread-forum as well, as we need information from Forum + relations.Add(ThreadEntity.Relations.ForumEntityUsingForumID); + // add the relation thread - SupportQueueThread and the relation SupportQueueThread - User, where we'll alias User. + relations.Add(ThreadEntity.Relations.SupportQueueThreadEntityUsingThreadID); + relations.Add(SupportQueueThreadEntity.Relations.UserEntityUsingPlacedInQueueByUserID, "PlacedInQueueUser"); + // add the relation supportqueuethread - user for the claiming user. We'll specify a left join, because a thread can be unclaimed. + relations.Add(SupportQueueThreadEntity.Relations.UserEntityUsingClaimedByUserID, "ClaimedThreadUser", JoinHint.Left); + + DataTable threadsInQueue = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + + dao.GetMultiAsDataTable(fields, threadsInQueue, 0, sorter, filter, relations, true, null, null, 0, 0); + return threadsInQueue.DefaultView; + } + + + /// + /// Gets the total number of threads in support queues. Only the count of threads which are in the forums in the list of + /// accessable forums are returned. + /// + /// A list of accessable forums IDs, which the user has permission to access. + /// total number of threads in support queues + public static int GetTotalNumberOfThreadsInSupportQueues(List accessableForums) + { + // return 0, if the user does not have a valid list of forums to access + if(accessableForums == null || accessableForums.Count <= 0) + { + return 0; + } + + PredicateExpression filter = new PredicateExpression(); + // only the forums the user has access to + filter.Add(ThreadFields.ForumID == accessableForums); + + // We'll a GetDbCount call to obtain the total number of threads which are in support queues + + // we need to join support queue with thread, so we can filter on thread's fields. We work with the intermediate entity + // 'SupportQueueThreadEntity' as we're not interested in the data, just the # of entries. + RelationCollection relations = new RelationCollection(); + relations.Add(SupportQueueThreadEntity.Relations.ThreadEntityUsingThreadID); + + SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); + return supportQueueThreads.GetDbCount(filter, relations); + } + } +} diff --git a/BL/SupportQueueManager.cs b/BL/SupportQueueManager.cs new file mode 100644 index 0000000..7b636e3 --- /dev/null +++ b/BL/SupportQueueManager.cs @@ -0,0 +1,243 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections.Generic; +using System.Text; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.HelperClasses; +using System.Data; +using SD.HnD.DAL.CollectionClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.BL +{ + /// + /// General class for support queue management related tasks + /// + public static class SupportQueueManager + { + /// + /// Creates a new support queue. + /// + /// Name of the queue. + /// The queue description. + /// The order no. + /// true if succeeded, false otherwise + public static bool CreateNewSupportQueue(string queueName, string queueDescription, short orderNo) + { + SupportQueueEntity toInsert = new SupportQueueEntity(); + toInsert.QueueDescription = queueDescription; + toInsert.QueueName = queueName; + toInsert.OrderNo = orderNo; + return toInsert.Save(); + } + + + /// + /// Modifies the support queue definition data. + /// + /// The queue ID of the queue to modify the definition data of. + /// Name of the queue. + /// The queue description. + /// The order no. + /// true if succeeded, false otherwise + public static bool ModifySupportQueue(int queueID, string queueName, string queueDescription, short orderNo) + { + SupportQueueEntity toModify = SupportQueueGuiHelper.GetSupportQueue(queueID); + if(toModify == null) + { + // not found + return false; + } + + // set the fields, if they're not changed, the field won't be updated in the db. + toModify.QueueName = queueName; + toModify.QueueDescription = queueDescription; + toModify.OrderNo = orderNo; + return toModify.Save(); + } + + + /// + /// Deletes the support queue with the ID specified. + /// + /// The queue ID of the queue to delete. + /// true if succeeded, false otherwise + /// All threads in the queue are automatically de-queued and not in a queue anymore. The Default support queue + /// for forums which have this queue as the default support queue is reset to null. + public static bool DeleteSupportQueue(int queueID) + { + // we'll do several actions in one atomic transaction, so start a transaction first. + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "DeleteSupportQ"); + + try + { + // first reset all the FKs in Forum to NULL if they point to this queue. + ForumEntity forumUpdater = new ForumEntity(); + // set the field to NULL. This is a nullable field, so we can just set the field to 'null', thanks to nullable types. + forumUpdater.DefaultSupportQueueID = null; + // update the entities directly in the db, use a forum collection for that + ForumCollection forums = new ForumCollection(); + trans.Add(forums); + // specify a filter that only the forums which have this queue as the default queue are updated and have their FK field set to NULL. + forums.UpdateMulti(forumUpdater, (ForumFields.DefaultSupportQueueID == queueID)); + + // delete all SupportQueueThread entities which refer to this queue. This will make all threads which are in this queue become queue-less. + SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); + trans.Add(supportQueueThreads); + // delete them directly from the db. + supportQueueThreads.DeleteMulti((SupportQueueThreadFields.QueueID == queueID)); + + // it's now time to delete the actual supportqueue entity. + SupportQueueCollection supportQueues = new SupportQueueCollection(); + trans.Add(supportQueues); + // delete it directly from the db. + int numberOfQueuesDeleted = supportQueues.DeleteMulti((SupportQueueFields.QueueID == queueID)); + + // done so commit the transaction. + trans.Commit(); + return (numberOfQueuesDeleted > 0); + } + catch + { + // first roll back the transaction + trans.Rollback(); + // then bubble up the exception + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Claims the thread specified for the user specified. As the thread can be in one queue at a time, it simply has to update the SupportQueueThread entity. + /// + /// The user ID. + /// The thread ID. + public static void ClaimThread(int userID, int threadID) + { + SupportQueueThreadEntity supportQueueThread = new SupportQueueThreadEntity(); + supportQueueThread.FetchUsingUCThreadID(threadID); + if(supportQueueThread.IsNew) + { + // not found, return + return; + } + + // simply overwrite an existing claim if any. + supportQueueThread.ClaimedByUserID = userID; + supportQueueThread.ClaimedOn = DateTime.Now; + + // done, save it + supportQueueThread.Save(); + } + + + /// + /// Releases the claim on the thread specified. As the thread can be in one queue at a time, it simply has to update the SupportQueueThread entity. + /// + /// The thread ID. + public static void ReleaseClaimOnThread(int threadID) + { + SupportQueueThreadEntity supportQueueThread = new SupportQueueThreadEntity(); + supportQueueThread.FetchUsingUCThreadID(threadID); + if(supportQueueThread.IsNew) + { + // not found, return + return; + } + + // simply reset an existing claim + supportQueueThread.ClaimedByUserID = null; // nullable type, so set to null. + supportQueueThread.ClaimedOn = null; // nullable type, so set to null. + + // done, save it + supportQueueThread.Save(); + } + + + /// + /// Persists the unit of work passed in with supportqueue entities. The call to this method originates from the form which manages support queues with + /// one LLBLGenProDataSource controls which is used to persist changes. This LLBLGenProDataSource produces a UnitOfWork when the + /// PerformWork event is raised and this UoW contains the changes to persist. This routine persists these changes. + /// + /// The unitofwork object which contains 1 or more changes (with standard .NET controls, this is 1) to persist. + /// + public static void PersistSupportQueueUnitOfWork(UnitOfWork uow) + { + // pass a new transaction to the commit routine and auto-commit this transaction when the transaction is complete. + uow.Commit(new Transaction(IsolationLevel.ReadCommitted, "PersistSupportQ"), true); + } + + + /// + /// Removes the thread with the threadid specified from the queue it's in. A thread can be in a single queue, so we don't need the queueID. + /// + /// The thread ID. + /// The transaction currently in progress. Can be null if no transaction is in progress. + public static void RemoveThreadFromQueue(int threadID, Transaction transactionToUse) + { + // delete the SupportQueueThread entity for this thread directly from the db, inside the transaction specified (if applicable) + SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); + if(transactionToUse != null) + { + // there's a transaction in progress, simply add it to the transaction + transactionToUse.Add(supportQueueThreads); + } + + // delete directly, using a filter on threadid + supportQueueThreads.DeleteMulti((SupportQueueThreadFields.ThreadID == threadID)); + + // don't commit the current transaction if specified, simply return to caller. + } + + + /// + /// Adds the thread with the ID specified to the support queue with the ID specified + /// + /// The thread ID. + /// The queue ID. + /// The user ID of the user causing this thread to be placed in the queue specified. + /// The transaction to use. Is not null if there's a transaction in progress. + /// first removes the thread from a queue if it's in a queue + public static void AddThreadToQueue(int threadID, int queueID, int userID, Transaction transactionToUse) + { + // first remove the thread from any queue it's in. + RemoveThreadFromQueue(threadID, transactionToUse); + + // then add it to the queue specified. + SupportQueueThreadEntity supportQueueThread = new SupportQueueThreadEntity(); + supportQueueThread.ThreadID = threadID; + supportQueueThread.QueueID = queueID; + supportQueueThread.PlacedInQueueByUserID = userID; + supportQueueThread.PlacedInQueueOn = DateTime.Now; + + if(transactionToUse != null) + { + // transaction in progress, add the entity to the transaction + transactionToUse.Add(supportQueueThread); + } + supportQueueThread.Save(); + } + } +} diff --git a/BL/SystemGuiHelper.cs b/BL/SystemGuiHelper.cs new file mode 100644 index 0000000..8255a6b --- /dev/null +++ b/BL/SystemGuiHelper.cs @@ -0,0 +1,47 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; + + +namespace SD.HnD.BL +{ + /// + /// General gui helper class for the system data + /// + public static class SystemGuiHelper + { + /// + /// Retrieves the current system settings, which is 1 row. + /// + /// DataTable with 1 row with the system settings. See TF_SystemData. + public static SystemDataEntity GetSystemSettings() + { + SystemDataCollection systemData = new SystemDataCollection(); + // get all entities, there's just 1 + systemData.GetMulti(null); + + // if the system is setup correctly, there's one entity + return systemData[0]; + } + } +} diff --git a/BL/SystemManager.cs b/BL/SystemManager.cs new file mode 100644 index 0000000..aca3866 --- /dev/null +++ b/BL/SystemManager.cs @@ -0,0 +1,67 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.BL +{ + /// + /// General System Settings Manager + /// + public static class SystemManager + { + /// + /// Will overwrite the system settings stored in SystemData. As there's just one record and that record is already there, it's just overwriting the + /// existing entity. + /// + /// The id. + /// The new default user role for new users. + /// The new anonymous role. + /// The new user title for new users. + /// The hours threshold for active threads. + /// The page size search results. + /// The minimal number of threads to fetch. + /// The minimal number of non sticky visible threads. + /// The setting to send notification emails or not. If set to false the system won't send + /// notification emails and users can't subscribe / unsubscribe to threads. + /// + /// true if save was succeeded, false otherwise + /// + public static bool StoreNewSystemSettings(int id, int newDefaultUserRoleNewUsers, int newAnonymousRole, int newUserTitleNewUsers, + short hoursThresholdForActiveThreads, short pageSizeSearchResults, short minimalNumberOfThreadsToFetch, + short minimalNumberOfNonStickyVisibleThreads, bool sendReplyNotifications) + { + // fetch the existing system data entity. + SystemDataEntity systemData = new SystemDataEntity(id); + + // update its parameters. + systemData.DefaultRoleNewUser = newDefaultUserRoleNewUsers; + systemData.AnonymousRole = newAnonymousRole; + systemData.DefaultUserTitleNewUser = newUserTitleNewUsers; + systemData.HoursThresholdForActiveThreads = hoursThresholdForActiveThreads; + systemData.PageSizeSearchResults = pageSizeSearchResults; + systemData.MinNumberOfNonStickyVisibleThreads = minimalNumberOfNonStickyVisibleThreads; + systemData.MinNumberOfThreadsToFetch = minimalNumberOfThreadsToFetch; + systemData.SendReplyNotifications = sendReplyNotifications; + return systemData.Save(); + } + } +} diff --git a/BL/ThreadGuiHelper.cs b/BL/ThreadGuiHelper.cs new file mode 100644 index 0000000..2c9a3e6 --- /dev/null +++ b/BL/ThreadGuiHelper.cs @@ -0,0 +1,507 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Web; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.TypedListClasses; + +namespace SD.HnD.BL +{ + /// + /// Class to provide essential data for the Thread Gui + /// + public static class ThreadGuiHelper + { + /// + /// Gets the thread. + /// + /// Thread ID. + /// Thread object or null if not found + public static ThreadEntity GetThread(int ID) + { + // load the entity from the database + ThreadEntity thread = new ThreadEntity(ID); + + //check if the entity is new (not found in the database), then return null. + if(thread.IsNew == true) + { + return null; + } + + return thread; + } + + + /// + /// Gets the thread subscription object for the thread - user combination passed in. If there's no subscription, null is returned. + /// + /// The thread ID. + /// The user ID. + /// requested Threadsubscription entity or null if not found + public static ThreadSubscriptionEntity GetThreadSubscription(int threadID, int userID) + { + return GetThreadSubscription(threadID, userID, null); + } + + + /// + /// Gets the thread subscription object for the thread - user combination passed in. If there's no subscription, null is returned. + /// + /// The thread ID. + /// The user ID. + /// The transaction to use. Pass in the transaction object if this fetch has to take place inside a transaction + /// + /// requested Threadsubscription entity or null if not found + /// + public static ThreadSubscriptionEntity GetThreadSubscription(int threadID, int userID, Transaction transactionToUse) + { + ThreadSubscriptionEntity toReturn = new ThreadSubscriptionEntity(); + if(transactionToUse != null) + { + // transaction in progress, add entity to it so it's not blocked + transactionToUse.Add(toReturn); + } + + // fetch the data + toReturn.FetchUsingPK(userID, threadID); + if(toReturn.IsNew) + { + // not found + return null; + } + + // done. Don't commit a passed in transaction here, it's controlled by the caller. + return toReturn; + } + + + /// + /// Gets the total number of messages in thread. + /// + /// The thread ID. + /// + public static int GetTotalNumberOfMessagesInThread(int threadID) + { + MessageCollection messages = new MessageCollection(); + return messages.GetDbCount((MessageFields.ThreadID == threadID)); + } + + + /// + /// Gets the active threads with statistics. + /// + /// A list of accessable forums IDs, which the user has permission to access. + /// The hours threshold for the query to fetch the active threads. All threads within this threshold's period of time (in hours) + /// are fetched. + /// The forums for which the calling user can view other users' threads. Can be null + /// The userid of the calling user. + /// + /// a dataTable of Active threads with statistics + /// + public static DataTable GetActiveThreadsStatisticsAsDataTable(List accessableForums, short hoursThreshold, + List forumsWithThreadsFromOthers, int userID) + { + // return null, if the user does not have a valid list of forums to access + if (accessableForums == null || accessableForums.Count <= 0) + { + return null; + } + + // create dyn. list and pull statistics using that list. + ResultsetFields fields = new ResultsetFields(3); + fields.DefineField(ThreadFields.ThreadID, 0, "AmountThreads", string.Empty, AggregateFunction.CountDistinct); + fields.DefineField(MessageFields.MessageID, 1, "AmountPostings", string.Empty, AggregateFunction.Count); + fields.DefineField(ThreadFields.ThreadLastPostingDate, 2, "LastPostingDate", string.Empty, AggregateFunction.Max); + + RelationCollection relations = new RelationCollection(); + relations.Add(ThreadEntity.Relations.MessageEntityUsingThreadID); + + PredicateExpression filter = new PredicateExpression(); + // only the forums the user has access to + filter.Add(ThreadFields.ForumID == accessableForums.ToArray()); + // only the threads which are not closed + filter.AddWithAnd(ThreadFields.IsClosed == false); + // only the threads which are active (== not done) + filter.AddWithAnd(ThreadFields.MarkedAsDone == false); + // only threads which have been updated in the last Globals.HoursForActiveThreadsTreshold hours + filter.AddWithAnd(ThreadFields.ThreadLastPostingDate >= DateTime.Now.AddHours((double)0 - hoursThreshold)); + + // Also filter on the threads viewable by the passed in userid, which is the caller of the method. If a forum isn't in the list of + // forumsWithThreadsFromOthers, only the sticky threads and the threads started by userid should be counted / taken into account. + PredicateExpression threadFilter = new PredicateExpression(); + if((forumsWithThreadsFromOthers!=null) && (forumsWithThreadsFromOthers.Count > 0)) + { + PredicateExpression onlyOwnThreadsFilter = new PredicateExpression(); + + // accept only those threads who aren't in the forumsWithThreadsFromOthers list and which are either started by userID or sticky. + // the filter on the threads not in the forums listed in the forumsWithThreadsFromOthers + if(forumsWithThreadsFromOthers.Count == 1) + { + // optimization, specify the only value instead of the range, so we won't get a WHERE Field IN (@param) query which is slow on some + // databases, but we'll get a WHERE Field == @param + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers[0])); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers[0]); + } + else + { + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers)); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers); + } + // the filter on either sticky or threads started by the calling user + onlyOwnThreadsFilter.AddWithAnd(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID==userID)); + threadFilter.AddWithOr(onlyOwnThreadsFilter); + } + else + { + // there are no forums enlisted in which the user has the right to view threads from others. So just filter on + // sticky threads or threads started by the calling user. + threadFilter.Add(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == userID)); + } + + filter.AddWithAnd(threadFilter); + + TypedListDAO dao = new TypedListDAO(); + DataTable toReturn = new DataTable(); + dao.GetMultiAsDataTable(fields, toReturn, 0, null, filter, relations, true, null, null, 0, 0); + return toReturn; + } + + + /// + /// Gets the active threads. + /// + /// A list of accessable forums IDs, which the user has permission to access. + /// The hours threshold for the query to fetch the active threads. All threads within this threshold's period of time (in hours) + /// are fetched. + /// The forums for which the calling user can view other users' threads. Can be null + /// The userid of the calling user. + /// a dataView of Active threads + public static DataView GetActiveThreadsAsDataView(List accessableForums, short hoursThreshold, + List forumsWithThreadsFromOthers, int userID) + { + // return null, if the user does not have a valid list of forums to access + if (accessableForums == null || accessableForums.Count <= 0) + { + return null; + } + + PredicateExpression filter = new PredicateExpression(); + // only the forums the user has access to + filter.Add(ThreadFields.ForumID == accessableForums); + // only the threads which are not closed + filter.Add(ThreadFields.IsClosed == false); + // only the threads which are active (== not done) + filter.Add(ThreadFields.MarkedAsDone == false); + // only threads which have been updated in the last Globals.HoursForActiveThreadsTreshold hours + filter.Add(ThreadFields.ThreadLastPostingDate >= DateTime.Now.AddHours((double)0 - hoursThreshold)); + + // Also filter on the threads viewable by the passed in userid, which is the caller of the method. If a forum isn't in the list of + // forumsWithThreadsFromOthers, only the sticky threads and the threads started by userid should be counted / taken into account. + PredicateExpression threadFilter = new PredicateExpression(); + if((forumsWithThreadsFromOthers!=null) && (forumsWithThreadsFromOthers.Count > 0)) + { + PredicateExpression onlyOwnThreadsFilter = new PredicateExpression(); + + // accept only those threads who aren't in the forumsWithThreadsFromOthers list and which are either started by userID or sticky. + // the filter on the threads not in the forums listed in the forumsWithThreadsFromOthers + if(forumsWithThreadsFromOthers.Count == 1) + { + // optimization, specify the only value instead of the range, so we won't get a WHERE Field IN (@param) query which is slow on some + // databases, but we'll get a WHERE Field == @param + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers[0])); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers[0]); + } + else + { + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers)); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers); + } + // the filter on either sticky or threads started by the calling user + onlyOwnThreadsFilter.AddWithAnd(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID==userID)); + threadFilter.AddWithOr(onlyOwnThreadsFilter); + } + else + { + // there are no forums enlisted in which the user has the right to view threads from others. So just filter on + // sticky threads or threads started by the calling user. + threadFilter.Add(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == userID)); + } + + filter.AddWithAnd(threadFilter); + + SortExpression sorter = new SortExpression(ThreadFields.ThreadLastPostingDate | SortOperator.Ascending); + + // We'll use a dynamic list to retrieve all threads which are 'active' and in the specified interval + ResultsetFields fields = BuildDynamicListForAllThreadsWithStats(); + int count = fields.Count; + // add 1 field to the resultset fields as we need data from Forum as well: + fields.Expand(1); + fields.DefineField(ForumFields.ForumName, count); + + // now build the relations for the dynamic list. We'll join User twice: once for the startuser and one for the lastpost user. + // also, we'll join the last message to the thread. The last message is joined with a custom filter added to the relation. + RelationCollection relations = BuildRelationsForAllThreadsWithStats(); + // add the relation thread-forum as well, as we need information from Forum + relations.Add(ThreadEntity.Relations.ForumEntityUsingForumID); + + DataTable activeThreads = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + + dao.GetMultiAsDataTable(fields, activeThreads, 0, sorter, filter, relations, true, null, null, 0, 0); + return activeThreads.DefaultView; + } + + + /// + /// Gets the last message in thread, and prefetches the user + usertitle entities. + /// + /// Thread ID. + /// fetched messageentity with the userentity + usertitle entity fetched as well of the user who posted the message. + public static MessageEntity GetLastMessageInThreadWithUserInfo(int threadID) + { + MessageCollection messages = new MessageCollection(); + PrefetchPath path = new PrefetchPath((int)EntityType.MessageEntity); + path.Add(MessageEntity.PrefetchPathPostedByUser).SubPath.Add(UserEntity.PrefetchPathUserTitle); + + messages.GetMulti( + new FieldCompareSetPredicate( + MessageFields.MessageID, + MessageFields.MessageID.SetObjectAlias("LastMessage"), + SetOperator.Equal, + new PredicateExpression(MessageFields.ThreadID == MessageFields.ThreadID.SetObjectAlias("LastMessage")) + .AddWithAnd(MessageFields.ThreadID==threadID), + null, + string.Empty, + 1, + new SortExpression(MessageFields.PostingDate.SetObjectAlias("LastMessage") | SortOperator.Descending) + ), 1, + null, + null, + path); + if(messages.Count<=0) + { + // not found + return null; + } + return messages[0]; + } + + + /// + /// Constructs a TypedList with all the messages in the thread given. Poster info is included, so the + /// returned dataview is bindable at once to the message list repeater. + /// + /// ID of Thread which messages should be returned + /// TypedList with all messages in the thread + public static MessagesInThreadTypedList GetAllMessagesInThreadAsTypedList(int threadID) + { + return GetAllMessagesInThreadAsTypedList(threadID, 0, 0); + } + + + /// + /// Constructs a TypedList with all the messages in the thread given. Poster info is included, so the + /// returned dataview is bindable at once to the message list repeater. + /// + /// ID of Thread which messages should be returned + /// The page no. + /// Size of the page. + /// TypedList with all messages in the thread for the page specified + public static MessagesInThreadTypedList GetAllMessagesInThreadAsTypedList(int threadID, int pageNo, int pageSize) + { + // we'll use a typedlist, MessagesInThread to pull the necessary data from the db. The typedlist contains fields from + // message, user and usertitle. + MessagesInThreadTypedList messages = new MessagesInThreadTypedList(); + + //create the filter with the threadID passed to the method. + PredicateExpression filter = new PredicateExpression(MessageFields.ThreadID == threadID); + + // Sort Messages on posting date, ascending, so the first post is located on top. + SortExpression sorter = new SortExpression(MessageFields.PostingDate | SortOperator.Ascending); + + // fetch the data into the typedlist. Pass in the paging information as well, to perform server-side paging. + messages.Fill(0, sorter, true, filter, null, null, pageNo, pageSize); + + // update thread entity directly inside the DB with a non-transactional update statement so the # of views is increased by one. + ThreadEntity updater = new ThreadEntity(); + // set the NumberOfViews field to an expression which increases it by 1 + updater.Fields[(int)ThreadFieldIndex.NumberOfViews].ExpressionToApply = (ThreadFields.NumberOfViews + 1); + updater.IsNew = false; + + // update the entity directly, and filter on the PK + ThreadCollection threads = new ThreadCollection(); + threads.UpdateMulti(updater, (ThreadFields.ThreadID == threadID)); + + // return the constructed typedlist + return messages; + } + + + /// + /// Will return the StartMessageNo for including it in the URL when redirecting to a page with messages in the given + /// thread. The page started with StartMessageNo will contain the message with ID messageID. Paging is done using the + /// maxAmountMessagesPerPage property in Application. + /// + /// ID of the thread to which the messages belong + /// + /// + public static int GetStartAtMessageForGivenMessageAndThread(int threadID, int messageID, int maxAmountMessagesPerPage) + { + //construct the dynamic list fields + ResultsetFields fields = new ResultsetFields(1); + fields.DefineField(MessageFields.MessageID, 0); + + //create the filter with the ID passed to the method. + PredicateExpression filter = new PredicateExpression(MessageFields.ThreadID == threadID); + + // Sort messages on postingdate / ascending + SortExpression sorter = new SortExpression(MessageFields.PostingDate | SortOperator.Ascending); + + // the value to be returned + int startAtMessage = 0; + int rowIndex = 0; + DataTable dynamicList = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + // Retrieves rows in the datatable provided which match the specified filter, containing the fields specified + dao.GetMultiAsDataTable(fields, dynamicList, 0, sorter, filter, null, false, null, null, 0, 0); + + if (dynamicList.Rows.Count > 0) + { + // there are messages. Find the row with messageID. There can be only one row with this messageID + for (int i = 0; i < dynamicList.Rows.Count; i++) + { + if (((int)dynamicList.Rows[i]["MessageID"]) == messageID) + { + // found the row + rowIndex = i; + break; + } + } + } + + startAtMessage = (rowIndex / maxAmountMessagesPerPage) * maxAmountMessagesPerPage; + + // done + return startAtMessage; + } + + + /// + /// Checks if the message with the ID specified is first message in thread with id specified. + /// + /// The thread ID. + /// The message ID. + /// true if message is first message in thread, false otherwise + public static bool CheckIfMessageIsFirstInThread(int threadID, int messageID) + { + // use a scalar query, which obtains the first MessageID in a given thread. We sort on posting date ascending, and simply read + // the first messageid. If that's not available or not equal to messageID, the messageID isn't the first post in the thread, otherwise it is. + ResultsetFields fields = new ResultsetFields(1); + fields.DefineField(MessageFields.MessageID, 0); + DataTable results = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + dao.GetMultiAsDataTable(fields, results, 1, new SortExpression(MessageFields.PostingDate | SortOperator.Ascending), + (MessageFields.ThreadID == threadID), null, true, null, null, 0, 0); + if(results.Rows.Count <= 0) + { + // not found + return false; + } + + return (((int)results.Rows[0][0]) == messageID); + } + + + /// + /// Builds the dynamic list for a query with all threads with statistics. + /// + /// setup in and ready to use resultset object + /// Doesn't add the forum fields + internal static ResultsetFields BuildDynamicListForAllThreadsWithStats() + { + ResultsetFields fields = new ResultsetFields(14); + fields.DefineField(ThreadFields.ThreadID, 0); + fields.DefineField(ThreadFields.ForumID, 1); + fields.DefineField(ThreadFields.Subject, 2); + fields.DefineField(ThreadFields.StartedByUserID, 3); + fields.DefineField(ThreadFields.ThreadLastPostingDate, 4); + fields.DefineField(ThreadFields.IsSticky, 5); + fields.DefineField(ThreadFields.IsClosed, 6); + fields.DefineField(ThreadFields.MarkedAsDone, 7); + fields.DefineField(ThreadFields.NumberOfViews, 8); + // the next field refers to an object alias, as we'll join User twice. + fields.DefineField(UserFields.NickName.SetObjectAlias("ThreadStarterUser"), 9); + // the next field is a scalar query with the # of postings in the thread. + fields.DefineField(new EntityField("AmountMessages", + new ScalarQueryExpression(MessageFields.MessageID.SetAggregateFunction(AggregateFunction.Count), + (MessageFields.ThreadID == ThreadFields.ThreadID)), typeof(int)), 10); + // the next two field refer to an object alias, as we'll join User twice. + fields.DefineField(UserFields.UserID, 11, "LastPostingByUserID", "LastPostingUser"); + fields.DefineField(UserFields.NickName, 12, "NickNameLastPosting", "LastPostingUser"); + // the next field sets the alias for the field to a different string than the default. + fields.DefineField(MessageFields.MessageID, 13, "LastMessageID", "LastMessage"); + + return fields; + } + + + /// + /// Builds the relation collection for a fetch of all threads with statistics. + /// + /// A ready to use relationcollection + /// Doesn't add the thread-forum relation. + internal static RelationCollection BuildRelationsForAllThreadsWithStats() + { + RelationCollection relations = new RelationCollection(); + relations.Add(ThreadEntity.Relations.UserEntityUsingStartedByUserID, "ThreadStarterUser", JoinHint.Left); + IEntityRelation threadMessage = ThreadEntity.Relations.MessageEntityUsingThreadID; + // the custom filter of the relation is a subquery which compares the messageID of the last message in the thread with the messageid of the set to join + threadMessage.CustomFilter = new PredicateExpression( + new FieldCompareSetPredicate(MessageFields.MessageID.SetObjectAlias("LastMessage"), + MessageFields.MessageID, SetOperator.Equal, + (MessageFields.ThreadID == MessageFields.ThreadID.SetObjectAlias("LastMessage")), null, string.Empty, 1, + new SortExpression(MessageFields.PostingDate | SortOperator.Descending))); + // now add the relation to the relationcollection, we'll alias the message entity in the relation so we can refer to it in our custom filter. + relations.Add(threadMessage, "LastMessage"); + relations.Add(MessageEntity.Relations.UserEntityUsingPostedByUserID, "LastMessage", "LastPostingUser", JoinHint.Left); + return relations; + } + + } +} diff --git a/BL/ThreadManager.cs b/BL/ThreadManager.cs new file mode 100644 index 0000000..ceaa3be --- /dev/null +++ b/BL/ThreadManager.cs @@ -0,0 +1,548 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Collections; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.Utility; +using System.Collections.Generic; +using System.Text; +using System.Web; +using System.Net.Mail; + +namespace SD.HnD.BL +{ + /// + /// General class for Thread management related tasks + /// + public static class ThreadManager + { + /// + /// Updates the memo field for the given thread + /// + /// Thread ID. + /// Memo. + /// + public static bool UpdateMemo(int threadID, string memo) + { + // load the entity from the database + ThreadEntity thread = ThreadGuiHelper.GetThread(threadID); + if(thread==null) + { + // not found + return false; + } + + thread.Memo = memo; + + //update the entity in the database + return thread.Save(); + } + + + /// + /// Marks the thread as done. + /// + /// Thread ID. + /// + public static bool MarkThreadAsDone(int threadID) + { + // load the entity from the database + ThreadEntity thread = ThreadGuiHelper.GetThread(threadID); + if(thread == null) + { + // not found + return false; + } + + // get the support queue the thread is in (if any) + SupportQueueEntity containingSupportQueue = SupportQueueGuiHelper.GetQueueOfThread(threadID); + thread.MarkedAsDone = true; + + // if the thread is in a support queue, the thread has to be removed from that queue. This is a multi-entity action and therefore we've to start a + // transaction if that's the case. If not, we can use the easy route and simply save the thread and be done with it. + if(containingSupportQueue == null) + { + // not in a queue, simply save the thread. + return thread.Save(); + } + + // in a queue, so remove from the queue and save the entity. + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "MarkThreadDone"); + trans.Add(thread); + try + { + // save the thread + bool result = thread.Save(); + if(result) + { + // save succeeded, so remove from queue, pass the current transaction to the method so the action takes place inside this transaction. + SupportQueueManager.RemoveThreadFromQueue(threadID, trans); + } + + trans.Commit(); + return true; + } + catch + { + // rollback transaction + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + /// + /// Marks the thread as un-done, and add it to the default queue of the forum. + /// + /// Thread ID + /// + public static bool UnMarkThreadAsDone(int threadID, int userID) + { + // load the entity from the database + ThreadEntity thread = ThreadGuiHelper.GetThread(threadID); + if (thread == null) + { + // not found + return false; + } + + thread.MarkedAsDone = false; + + ForumEntity forum = new ForumEntity(thread.ForumID); + + // Save the thread and add it to the default queue of the forum. + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "MarkThreadUnDone"); + trans.Add(thread); + try + { + thread.Save(); + + if ((forum.Fields.State == EntityState.Fetched) && (forum.DefaultSupportQueueID.HasValue)) + { + // not in a queue, and the forum has a default queue. Add the thread to the queue of the forum + SupportQueueManager.AddThreadToQueue(threadID, forum.DefaultSupportQueueID.Value, userID, trans); + } + + trans.Commit(); + return true; + } + catch + { + // rollback transaction + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + /// + /// Creates a new message in the given thread + /// Caller should validate input parameters. + /// + /// Thread wherein the new message will be placed + /// User who posted this message + /// Message text + /// Message text as HTML + /// IP address of user calling this method + /// Message text as XML, which is the result of the parse action on MessageText. + /// if set to true [subscribe to thread]. + /// The thread updated notification template. + /// The email data. + /// Flag to signal to send reply notifications. If set to false no notifications are mailed, + /// otherwise a notification is mailed to all subscribers to the thread the new message is posted in + /// MessageID if succeeded, 0 if not. + public static int CreateNewMessageInThread(int threadID, int userID, string messageText, string messageAsHTML, string userIDIPAddress, + string messageAsXML, bool subscribeToThread, string threadUpdatedNotificationTemplate, Dictionary emailData, + bool sendReplyNotifications) + { + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "InsertNewMessage"); + int messageID = 0; + try + { + DateTime postingDate = DateTime.Now; + messageID = InsertNewMessage(threadID, userID, messageText, messageAsHTML, userIDIPAddress, messageAsXML, trans, postingDate); + MessageManager.UpdateStatisticsAfterMessageInsert(threadID, userID, trans, postingDate, true, subscribeToThread); + trans.Commit(); + } + catch(Exception) + { + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + + if(sendReplyNotifications) + { + // send notification email to all subscribers. Do this outside the transaction so a failed email send action doesn't terminate the save process + // of the message. + ThreadManager.SendThreadReplyNotifications(threadID, userID, threadUpdatedNotificationTemplate, emailData); + } + return messageID; + } + + + /// + /// Creates a new message in the given thread and closes the thread right after the addition of the message, + /// which makes the just added message the 'close' message of the thread. Close messages are handy when the + /// closure of a thread is not obvious. + /// Caller should validate input parameters. + /// + /// Thread wherein the new message will be placed + /// User who posted this message + /// Message text + /// Message text as HTML + /// IP address of user calling this method + /// Message text as XML, which is the result of the parse action on MessageText. + /// The thread updated notification template. + /// The email data. + /// Flag to signal to send reply notifications. If set to false no notifications are mailed, + /// otherwise a notification is mailed to all subscribers to the thread the new message is posted in + /// MessageID if succeeded, 0 if not. + public static int CreateNewMessageInThreadAndCloseThread(int threadID, int userID, string messageText, string messageAsHTML, + string userIDIPAddress, string messageAsXML, string threadUpdatedNotificationTemplate, Dictionary emailData, + bool sendReplyNotifications) + { + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "InsertNewMessage"); + int messageID = 0; + try + { + DateTime postingDate = DateTime.Now; + messageID = InsertNewMessage(threadID, userID, messageText, messageAsHTML, userIDIPAddress, messageAsXML, trans, postingDate); + + MessageManager.UpdateStatisticsAfterMessageInsert(threadID, userID, trans, postingDate, false, false); + + ThreadEntity thread = new ThreadEntity(); + trans.Add(thread); + thread.FetchUsingPK(threadID); + thread.IsClosed=true; + thread.IsSticky=false; + thread.MarkedAsDone = true; + bool result = thread.Save(); + if(result) + { + // save succeeded, so remove from queue, pass the current transaction to the method so the action takes place inside this transaction. + SupportQueueManager.RemoveThreadFromQueue(threadID, trans); + } + + trans.Commit(); + } + catch(Exception) + { + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + + if(sendReplyNotifications) + { + // send notification email to all subscribers. Do this outside the transaction so a failed email send action doesn't terminate the save process + // of the message. + ThreadManager.SendThreadReplyNotifications(threadID, userID, threadUpdatedNotificationTemplate, emailData); + } + return messageID; + } + + + /// + /// Modifies the given properties of the given thread. + /// + /// The threadID of the thread which properties should be changed + /// The new subject for this thread + /// The new value for IsSticky + /// The new value for IsClosed + /// + public static bool ModifyThreadProperties(int threadID, string subject, bool isSticky, bool isClosed) + { + // load the entity from the database + ThreadEntity thread = ThreadGuiHelper.GetThread(threadID); + if(thread == null) + { + // not found + return false; + } + + // update the fields with new values + thread.Subject = subject; + thread.IsSticky = isSticky; + thread.IsClosed = isClosed; + + // save the updated entity back to the database + return thread.Save(); + } + + + /// + /// Moves the given thread to the given forum. + /// + /// ID of thread to move + /// ID of forum to move the thread to + /// + public static bool MoveThread(int threadID, int newForumID) + { + // load the entity from the database + ThreadEntity thread = ThreadGuiHelper.GetThread(threadID); + if(thread == null) + { + // not found + return false; + } + + // update the ForumID field with the new value + thread.ForumID = newForumID; + + // save the updated entity back to the database + return thread.Save(); + } + + + /// + /// Deletes the given Thread from the system, including all messages and related data in this Thread. + /// + /// Thread to delete. + /// True if succeeded, false otherwise + public static bool DeleteThread(int threadID) + { + // trying to delete the entity directly from the database without first loading it. + // for that we use an entity collection and use the DeleteMulti method with a filter on the PK. + PredicateExpression threadFilter = new PredicateExpression(ThreadFields.ThreadID == threadID); + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "DeleteThread"); + try + { + DeleteThreads(threadFilter, trans); + trans.Commit(); + return true; + } + catch + { + // error occured + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Deletes all threads in the specified forum. + /// + /// The forum filter. + /// The transaction to use. + internal static void DeleteAllThreadsInForum(int forumID, Transaction trans) + { + // fabricate the threadfilter, based on the passed in forumId. We do this by creating a FieldCompareValuePredicate: + // WHERE Thread.ForumID = forumID + PredicateExpression threadFilter = new PredicateExpression(); + threadFilter.Add(ThreadFields.ForumID == forumID); + DeleteThreads(threadFilter, trans); + } + + + /// + /// Deletes the threads matching the passed in filter, inside the transaction specified. + /// + /// The thread filter. + /// The transaction to use. + private static void DeleteThreads(PredicateExpression threadFilter, Transaction trans) + { + // we've to perform a set of actions in a given order to make sure we're not violating FK constraints in the DB. + + // delete messages in thread + MessageManager.DeleteAllMessagesInThreads(threadFilter, trans); + + // delete bookmarks (if exists) of the threads to be deleted + BookmarkCollection bookmarks = new BookmarkCollection(); + trans.Add(bookmarks); + // use again a fieldcompareset predicate + bookmarks.DeleteMulti(new FieldCompareSetPredicate(BookmarkFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); + + // delete audit info related to this thread. Can't be done directly on the db due to the fact the entities are in a TargetPerEntity hierarchy, which + // can't be deleted directly on the db, so we've to fetch the entities first. + AuditDataThreadRelatedCollection threadAuditData = new AuditDataThreadRelatedCollection(); + trans.Add(threadAuditData); + // use a fieldcompareset predicate filter, based on the threadFilter. + threadAuditData.GetMulti(new FieldCompareSetPredicate(AuditDataThreadRelatedFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); + threadAuditData.DeleteMulti(); + + // delete support queue thread entity for this thread (if any) + SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); + trans.Add(supportQueueThreads); + // use again a fieldcompareset predicate + supportQueueThreads.DeleteMulti(new FieldCompareSetPredicate(SupportQueueThreadFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); + + // delete threadsubscription entities + ThreadSubscriptionCollection threadSubscriptions = new ThreadSubscriptionCollection(); + trans.Add(threadSubscriptions); + // use again a fieldcompareset predicate + threadSubscriptions.DeleteMulti(new FieldCompareSetPredicate(ThreadSubscriptionFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); + + // delete the threads + ThreadCollection threads = new ThreadCollection(); + trans.Add(threads); + // we already have the filter to use, namely the filter passed in. + threads.DeleteMulti(threadFilter); + + // don't commit the transaction, that's up to the caller. + } + + + /// + /// Inserts a new message in thread given. All exceptions are passed upwards, caller has full control over transaction. + /// + /// Thread wherein the new message will be placed + /// User who posted this message + /// Message text + /// Message text as HTML + /// IP address of user calling this method + /// Message text as XML, which is the result of the parse action on MessageText. + /// the open transaction to use for saving this message. + /// The posting date. + /// new messageid + private static int InsertNewMessage(int threadID, int userID, string messageText, string messageAsHTML, string userIDIPAddress, + string messageAsXML, Transaction transactionToUse, DateTime postingDate) + { + MessageEntity message = new MessageEntity(); + message.MessageText = messageText; + message.MessageTextAsHTML = messageAsHTML; + message.PostedByUserID = userID; + message.PostingDate = postingDate; + message.ThreadID = threadID; + message.PostedFromIP = userIDIPAddress; + message.MessageTextAsXml = messageAsXML; + transactionToUse.Add(message); + bool result = message.Save(); + if(result) + { + return message.MessageID; + } + else + { + return 0; + } + } + + + /// + /// Sends email to all users subscribed to a specified thread, except the user who initiated the thread update. + /// + /// The thread that was updated. + /// The user who initiated the update (who will not receive notification). + private static void SendThreadReplyNotifications(int threadID, int initiatedByUserID, string emailTemplate, + Dictionary emailData) + { + // get list of subscribers to thread, minus the initiator. Do this by fetching the subscriptions plus the related user entity entity instances. + // The related user entities are loaded using a prefetch path. + ThreadSubscriptionCollection subscriptions = new ThreadSubscriptionCollection(); + PrefetchPath prefetch = new PrefetchPath((int)EntityType.ThreadSubscriptionEntity); + prefetch.Add(ThreadSubscriptionEntity.PrefetchPathUser); + + // we're interested in subscriptions on the specified thread and for all users who aren't the initiating user. + PredicateExpression predicate = new PredicateExpression(); + predicate.Add(ThreadSubscriptionFields.ThreadID == threadID); + predicate.AddWithAnd(ThreadSubscriptionFields.UserID != initiatedByUserID); + + // fetch all subscriptions, using the filter and the prefetch path. + subscriptions.GetMulti(predicate, prefetch); + + // now collect all email addresses into an array so we can pass that to the email routine. + string[] toAddresses = new string[subscriptions.Count]; + + for(int i=0;i + /// Class to provide essential data for the User gui + /// + public static class UserGuiHelper + { + /// + /// Gets the bookmark statistics for the user with id passed in. + /// + /// User ID. + /// + public static DataTable GetBookmarkStatisticsAsDataTable(int userID) + { + // create dyn. list and pull statistics using that list. + ResultsetFields fields = new ResultsetFields(3); + fields.DefineField(BookmarkFields.ThreadID, 0, "AmountThreads", AggregateFunction.CountDistinct); + fields.DefineField(MessageFields.MessageID, 1, "AmountPostings", AggregateFunction.Count); + fields.DefineField(ThreadFields.ThreadLastPostingDate, 2, "LastPostingDate", AggregateFunction.Max); + + // the dynamic list is build on several entities, build the relations collection with the relations between these entities. + RelationCollection relations = new RelationCollection(); + relations.Add(BookmarkEntity.Relations.ThreadEntityUsingThreadID); + relations.Add(ThreadEntity.Relations.MessageEntityUsingThreadID); + + // set up the filter: only bookmarks for the user passed in. + PredicateExpression filter = new PredicateExpression(BookmarkFields.UserID == userID); + + TypedListDAO dao = new TypedListDAO(); + DataTable toReturn = new DataTable(); + dao.GetMultiAsDataTable(fields, toReturn, 0, null, filter, relations, true, null, null, 0, 0); + + return toReturn; + } + + + /// + /// Gets all the banned users as a dataview. This is returned as a dataview because only the nicknames are required, so a dynamic list is + /// used to avoid unnecessary data fetching. + /// + /// dataview with the nicknames of the users which are banned on the useraccount: the IsBanned property is set for these users. + /// This list of nicknames is cached in the application object so these users can be logged off by force. + public static DataView GetAllBannedUserNicknamesAsDataView() + { + ResultsetFields fields = new ResultsetFields(1); + fields.DefineField(UserFields.NickName, 0); + + TypedListDAO dao = new TypedListDAO(); + DataTable results = new DataTable(); + dao.GetMultiAsDataTable(fields, results, 0, null, (UserFields.IsBanned == true), null, true, null, null, 0, 0); + + return results.DefaultView; + } + + + /// + /// Gets the last n threads in which the user specified participated with one or more messages. Threads which aren't visible for the + /// calling user are filtered out. + /// + /// A list of accessable forums IDs, which the user calling the method has permission to access. + /// The participant user ID of the user of which the threads have to be obtained. + /// The forums with threads from others. + /// The calling user ID. + /// The amount of threads to fetch. + /// a dataView of the threads requested + public static DataView GetLastThreadsForUserAsDataView(List accessableForums, int participantUserID, + List forumsWithThreadsFromOthers, int callingUserID, int amount) + { + return GetLastThreadsForUserAsDataView(accessableForums, participantUserID, forumsWithThreadsFromOthers, callingUserID, amount, 0); + } + + /// + /// Gets the last pageSize threads in which the user specified participated with one or more messages for the page specified. + /// Threads which aren't visible for the calling user are filtered out. If pageNumber is 0, pageSize is used to limit the list to the pageSize + /// + /// A list of accessable forums IDs, which the user calling the method has permission to access. + /// The participant user ID of the user of which the threads have to be obtained. + /// The forums with threads from others. + /// The calling user ID. + /// Size of the page. + /// The page number to fetch. + /// a dataView of the threads requested + public static DataView GetLastThreadsForUserAsDataView(List accessableForums, int participantUserID, + List forumsWithThreadsFromOthers, int callingUserID, int pageSize, int pageNumber) + { + // return null, if the user does not have a valid list of forums to access + if(accessableForums == null || accessableForums.Count <= 0) + { + return null; + } + + int numberOfThreadsToFetch = pageSize; + if(numberOfThreadsToFetch <= 0) + { + numberOfThreadsToFetch = 25; + } + + PredicateExpression filter = CreateFilterForLastThreadsForUser(accessableForums, participantUserID, forumsWithThreadsFromOthers, callingUserID); + SortExpression sorter = new SortExpression(ThreadFields.ThreadLastPostingDate | SortOperator.Descending); + + // We'll use a dynamic list to retrieve the threads info + ResultsetFields fields = ThreadGuiHelper.BuildDynamicListForAllThreadsWithStats(); + int count = fields.Count; + + // now build the relations for the dynamic list. We'll join User twice: once for the startuser and one for the lastpost user. + // also, we'll join the last message to the thread. The last message is joined with a custom filter added to the relation. + RelationCollection relations = ThreadGuiHelper.BuildRelationsForAllThreadsWithStats(); + + DataTable lastThreads = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + + if(pageNumber <= 0) + { + // no paging + // get the last numberOfThreadsToFetch, so specify a limit equal to the numberOfThreadsToFetch specified + dao.GetMultiAsDataTable(fields, lastThreads, numberOfThreadsToFetch, sorter, filter, relations, true, null, null, 0, 0); + } + else + { + // use paging + dao.GetMultiAsDataTable(fields, lastThreads, 0, sorter, filter, relations, true, null, null, pageNumber, numberOfThreadsToFetch); + } + return lastThreads.DefaultView; + } + + + /// + /// Gets the row count for the set of threads in which the user specified participated with one or more messages for the page specified. + /// Threads which aren't visible for the calling user are filtered out. + /// + /// A list of accessable forums IDs, which the user calling the method has permission to access. + /// The participant user ID of the user of which the threads have to be obtained. + /// The forums with threads from others. + /// The calling user ID. + /// a dataView of the threads requested + public static int GetRowCountLastThreadsForUserAsDataView(List accessableForums, int participantUserID, + List forumsWithThreadsFromOthers, int callingUserID) + { + // return null, if the user does not have a valid list of forums to access + if(accessableForums == null || accessableForums.Count <= 0) + { + return 0; + } + + PredicateExpression filter = CreateFilterForLastThreadsForUser(accessableForums, participantUserID, forumsWithThreadsFromOthers, callingUserID); + SortExpression sorter = new SortExpression(ThreadFields.ThreadLastPostingDate | SortOperator.Descending); + + // We'll use a dynamic list to retrieve the threads info + ResultsetFields fields = ThreadGuiHelper.BuildDynamicListForAllThreadsWithStats(); + int count = fields.Count; + + // now build the relations for the dynamic list. We'll join User twice: once for the startuser and one for the lastpost user. + // also, we'll join the last message to the thread. The last message is joined with a custom filter added to the relation. + RelationCollection relations = ThreadGuiHelper.BuildRelationsForAllThreadsWithStats(); + + TypedListDAO dao = new TypedListDAO(); + return dao.GetDbCount(fields, null, filter, relations, null, false); + } + + + /// + /// Creates the filter for last threads for user code + /// + /// The accessable forums. + /// The participant user ID. + /// The forums with threads from others. + /// The calling user ID. + /// + private static PredicateExpression CreateFilterForLastThreadsForUser(List accessableForums, int participantUserID, List forumsWithThreadsFromOthers, int callingUserID) + { + PredicateExpression filter = new PredicateExpression(); + + // only the forums the calling user has access to + filter.Add(ThreadFields.ForumID == accessableForums); + // only the threads in which the participant user has posted one or more posts in. Do this with a fieldcompareset predicate + // to create the clause: + // where threadid in (select threadid from message where postedbyuserid = the participaintuserid specified.) + filter.AddWithAnd(new FieldCompareSetPredicate(ThreadFields.ThreadID, MessageFields.ThreadID, SetOperator.In, + (MessageFields.PostedByUserID == participantUserID))); + + // Also filter on the threads viewable by the passed in userid, which is the caller of the method. If a forum isn't in the list of + // forumsWithThreadsFromOthers, only the sticky threads and the threads started by userid should be counted / taken into account. + PredicateExpression threadFilter = new PredicateExpression(); + if((forumsWithThreadsFromOthers != null) && (forumsWithThreadsFromOthers.Count > 0)) + { + PredicateExpression onlyOwnThreadsFilter = new PredicateExpression(); + + // accept only those threads who aren't in the forumsWithThreadsFromOthers list and which are either started by userID or sticky. + // the filter on the threads not in the forums listed in the forumsWithThreadsFromOthers + if(forumsWithThreadsFromOthers.Count == 1) + { + // optimization, specify the only value instead of the range, so we won't get a WHERE Field IN (@param) query which is slow on some + // databases, but we'll get a WHERE Field == @param + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers[0])); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers[0]); + } + else + { + // accept all threads which are in a forum located in the forumsWithThreadsFromOthers list + threadFilter.Add((ThreadFields.ForumID == forumsWithThreadsFromOthers)); + onlyOwnThreadsFilter.Add(ThreadFields.ForumID != forumsWithThreadsFromOthers); + } + // the filter on either sticky or threads started by the calling user + onlyOwnThreadsFilter.AddWithAnd(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == callingUserID)); + threadFilter.AddWithOr(onlyOwnThreadsFilter); + } + else + { + // there are no forums enlisted in which the user has the right to view threads from others. So just filter on + // sticky threads or threads started by the calling user. + threadFilter.Add(new PredicateExpression(ThreadFields.IsSticky == true) + .AddWithOr(ThreadFields.StartedByUserID == callingUserID)); + } + + filter.AddWithAnd(threadFilter); + + return filter; + } + + + /// + /// Finds the users matching the filter criteria. + /// + /// if [filter on role]; otherwise, . + /// Role ID. + /// if [filter on nick name]; otherwise, . + /// Name of the nick. + /// if [filter on email address]; otherwise, . + /// Email address. + /// User objects matching the query + public static UserCollection FindUsers(bool filterOnRole, int roleID, bool filterOnNickName, string nickName, bool filterOnEmailAddress, string emailAddress) + { + PredicateExpression filter = new PredicateExpression(); + if(filterOnRole) + { + filter.Add(new FieldCompareSetPredicate(UserFields.UserID, RoleUserFields.UserID, SetOperator.In, (RoleUserFields.RoleID == roleID))); + } + if(filterOnNickName) + { + filter.Add((UserFields.NickName % ("%" + nickName + "%"))); + } + if(filterOnEmailAddress) + { + filter.Add((UserFields.EmailAddress % ("%" + emailAddress + "%"))); + } + + UserCollection toReturn = new UserCollection(); + toReturn.GetMulti(filter, 0, new SortExpression(UserFields.NickName | SortOperator.Ascending)); + return toReturn; + } + + + /// + /// Checks the if thread is already bookmarked. + /// + /// User ID. + /// Thread ID. + /// true if the thread is bookmarked + public static bool CheckIfThreadIsAlreadyBookmarked(int userID, int threadID) + { + BookmarkCollection bookmarks = new BookmarkCollection(); + PredicateExpression filter = new PredicateExpression((BookmarkFields.ThreadID == threadID) & (BookmarkFields.UserID == userID)); + return (bookmarks.GetScalar(BookmarkFieldIndex.ThreadID, null, AggregateFunction.None, filter)!=null); + } + + + /// + /// Gets the bookmarks with statistics for the user specified. + /// + /// User ID. + /// + public static DataView GetBookmarksAsDataView(int userID) + { + FieldCompareSetPredicate filter = new FieldCompareSetPredicate( + ThreadFields.ThreadID, BookmarkFields.ThreadID, SetOperator.In, (BookmarkFields.UserID == userID)); + + SortExpression sorter = new SortExpression(ThreadFields.ThreadLastPostingDate | SortOperator.Descending); + + // We'll use a dynamic list to retrieve all threads which are bookmarked by the user. + ResultsetFields fields = ThreadGuiHelper.BuildDynamicListForAllThreadsWithStats(); + // add 2 fields to the resultset fields as we need data from Forum as well: + int count = fields.Count; + fields.Expand(2); + fields.DefineField(ForumFields.ForumName, count); + fields.DefineField(ForumFields.SectionID, count+1); + + // now build the relations for the dynamic list. We'll join User twice: once for the startuser and one for the lastpost user. + // also, we'll join the last message to the thread. The last message is joined with a custom filter added to the relation. + RelationCollection relations = ThreadGuiHelper.BuildRelationsForAllThreadsWithStats(); + // add the relation thread-forum as well, as we need information from Forum + relations.Add(ThreadEntity.Relations.ForumEntityUsingForumID); + + DataTable bookmarkedThreads = new DataTable(); + TypedListDAO dao = new TypedListDAO(); + dao.GetMultiAsDataTable(fields, bookmarkedThreads, 0, sorter, filter, relations, true, null, null, 0, 0); + return bookmarkedThreads.DefaultView; + } + + + /// + /// Retrieves all available usertitles. + /// + /// entitycollection with all the usertitles + public static UserTitleCollection GetAllUserTitles() + { + UserTitleCollection userTitles = new UserTitleCollection(); + userTitles.GetMulti(null); + return userTitles; + } + + + /// + /// Checks if the given nickname is already taken. If so, true is returned, otherwise false. + /// + /// NickName to check + /// true if nickname already exists in the database, false otherwise + public static bool CheckIfNickNameExists(string nickName) + { + UserEntity user = new UserEntity(); + user.FetchUsingUCNickName(nickName); + return !user.IsNew; + } + + + /// + /// Returns an entity collection with all User entities of users who are not currently in the given Role + /// + /// Role to use as filter + /// entitycollection with data requested + public static UserCollection GetAllUsersNotInRole(int roleID) + { + // we're going to use the query: + // SELECT ... FROM User + // WHERE UserID NOT IN (SELECT UserID FROM RoleUser WHERE RoleID = @roleID) + // so define the filter as a fieldcompareset predicate where we use the roleid in the filter and negate the predicate so it will emit NOT IN + PredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareSetPredicate(UserFields.UserID, RoleUserFields.UserID, + SetOperator.In, (RoleUserFields.RoleID == roleID), true)); + + // sort on nickname ascending + SortExpression sorter = new SortExpression(UserFields.NickName | SortOperator.Ascending); + UserCollection users = new UserCollection(); + users.GetMulti(filter, 0, sorter); + return users; + } + + + /// + /// Gets all users in range specified + /// + /// Range with userids + /// + public static UserCollection GetAllUsersInRange(List range) + { + UserCollection users = new UserCollection(); + users.GetMulti((UserFields.UserID==range)); + return users; + } + + + /// + /// Returns a UserCollection with all User entities of users who are currently in the given Role + /// + /// Role to use as filter + /// UserCollection with data requested + public static UserCollection GetAllUsersInRole(int roleID) + { + // we're going to use the query: + // SELECT ... FROM User + // WHERE UserID IN (SELECT UserID FROM RoleUser WHERE RoleID = @roleID) + // so define the filter as a fieldcompareset predicate where we use the roleid in the filter + PredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareSetPredicate(UserFields.UserID, RoleUserFields.UserID, + SetOperator.In, (RoleUserFields.RoleID == roleID))); + + // sort on nickname ascending + SortExpression sorter = new SortExpression(UserFields.NickName | SortOperator.Ascending); + + UserCollection users = new UserCollection(); + users.GetMulti(filter, 0, sorter); + return users; + } + + + /// + /// Returns the user entity of the user with ID userID + /// + /// The user ID. + /// entity with data requested or null if not found. + public static UserEntity GetUser(int userID) + { + UserEntity user = new UserEntity(userID); + if(user.IsNew) + { + // not found + return null; + } + return user; + } + + /// + /// Returns the user entity of the user with ID userID, With A UserEntityTitle prefetched. + /// + /// The user ID. + /// entity with data requested + public static UserEntity GetUserWithTitleDescription(int userID) + { + PrefetchPath prefetchPath = new PrefetchPath((int)EntityType.UserEntity); + prefetchPath.Add(UserEntity.PrefetchPathUserTitle); + + UserEntity user = new UserEntity(userID, prefetchPath); + if(user.IsNew) + { + // not found + return null; + } + return user; + } + + + /// + /// Checks if thread is already subscribed. If so, true is returned otherwise false. + /// + /// The user ID. + /// The thread ID. + /// true if the user is already subscribed to this thread otherwise false + public static bool CheckIfThreadIsAlreadySubscribed(int userID, int threadID) + { + return (ThreadGuiHelper.GetThreadSubscription(threadID, userID) != null); + } + } +} diff --git a/BL/UserManager.cs b/BL/UserManager.cs new file mode 100644 index 0000000..7bba8c3 --- /dev/null +++ b/BL/UserManager.cs @@ -0,0 +1,519 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Data.SqlTypes; +using SD.HnD.Utility; +using SD.HnD.DAL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.DaoClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; +using System.Security.Cryptography; +using System.Web; + +namespace SD.HnD.BL +{ + /// + /// Special exception which is thrown when a password reset action was executed but the nickname specified wasn't found. + /// + public class NickNameNotFoundException: System.ApplicationException + { + public NickNameNotFoundException(string sMessage):base(sMessage) + { + } + } + + + /// + /// Special exception which is thrown when a password reset action was executed but the email specified doesn't match the nickname specified. + /// + public class EmailAddressDoesntMatchException: System.ApplicationException + { + public EmailAddressDoesntMatchException(string sMessage):base(sMessage) + { + } + } + + + /// + /// General class for Usermanagement related tasks + /// + public static class UserManager + { + /// + /// Adds the thread to bookmarks. + /// + /// User ID. + /// Thread ID. + /// true if save succeeded, false otherwise + public static bool AddThreadToBookmarks(int userID, int threadID) + { + BookmarkEntity newBookmark = new BookmarkEntity(); + newBookmark.UserID = userID; + newBookmark.ThreadID = threadID; + return newBookmark.Save(); + } + + + /// + /// Unsubscribes the specified user from the specified thread. + /// + /// The thread ID. + /// The user ID. + /// true if delete succeeded, false otherwise + public static bool RemoveSingleSubscription(int threadID, int userID) + { + ThreadSubscriptionEntity subscription = ThreadGuiHelper.GetThreadSubscription(threadID, userID); + if(subscription != null) + { + // there's a subscription, delete it + return subscription.Delete(); + } + else + { + return true; + } + } + + + /// + /// Subscribes the user specified to the thread specified for notifications. A transaction can be specified to save the information inside the + /// transaction specified. If the user is already subscribed to this thread, nothing is done + /// + /// The thread ID. + /// The user ID. + /// The transaction to use. If no transaction is specified, no transaction is created + /// + public static bool AddThreadToSubscriptions(int threadID, int userID, Transaction transactionToUse) + { + // check if this user is already subscribed to this thread. If not, add a new subscription. + ThreadSubscriptionEntity subscription = ThreadGuiHelper.GetThreadSubscription(threadID, userID, transactionToUse); + if(subscription == null) + { + // user isn't yet subscribed, add the subscription + subscription = new ThreadSubscriptionEntity(); + subscription.UserID = userID; + subscription.ThreadID = threadID; + if(transactionToUse != null) + { + transactionToUse.Add(subscription); + } + return subscription.Save(); + } + // already subscribed, no-op. + return true; + } + + + /// + /// Updates the last visit date for user. + /// + /// The user ID of the user to update the date for. + public static void UpdateLastVisitDateForUser(int userID) + { + UserEntity user = UserGuiHelper.GetUser(userID); + if(user == null) + { + // not found + return; + } + user.LastVisitedDate = DateTime.Now; + user.Save(); + return; + } + + + /// + /// Toggles the ban flag value. + /// + /// The user ID of the user to toggle the ban flag. + /// true if toggle was succesful, false otherwise + public static bool ToggleBanFlagValue(int userID, out bool newBanFlagValue) + { + newBanFlagValue = false; + UserEntity user = UserGuiHelper.GetUser(userID); + if(user == null) + { + return false; + } + + newBanFlagValue = !user.IsBanned; + user.IsBanned = newBanFlagValue; + return user.Save(); + } + + + /// + /// Deletes the user with the ID passed in. Will reset all posts made by the user to the userid 0. + /// + /// The user ID. + /// Can't delete user 0 + /// true if succeeded, false otherwise + public static bool DeleteUser(int userID) + { + if(userID == 0) + { + // can't delete the Anonymous coward user. + return false; + } + + UserEntity toDelete = UserGuiHelper.GetUser(userID); + if(toDelete==null) + { + // user doesn't exist + return false; + } + + // all actions have to take place in a transaction. + Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "DeleteUser"); + + try + { + // we'll first update all PostedByUserId fields of all messages which are posted by the user to delete. + MessageEntity messageUpdater = new MessageEntity(); + messageUpdater.PostedByUserID = 0; // reset to AC. + MessageCollection messages = new MessageCollection(); + trans.Add(messages); // add to the transaction + // update all entities directly in the DB, which match the following filter and update them with the new values set in messageUpdater. + messages.UpdateMulti(messageUpdater, (MessageFields.PostedByUserID == userID)); + + // set the startuser of threads started by this user to 0 + ThreadEntity threadUpdater = new ThreadEntity(); + threadUpdater.StartedByUserID = 0; + ThreadCollection threads = new ThreadCollection(); + trans.Add(threads); + threads.UpdateMulti(threadUpdater, (ThreadFields.StartedByUserID == userID)); + + // remove the user from the UserRoles set, as the user shouldn't be in any roles. + RoleUserCollection roleUsersDeleter = new RoleUserCollection(); + trans.Add(roleUsersDeleter); + // delete all entities directly from the DB which match the following filter. + roleUsersDeleter.DeleteMulti(RoleUserFields.UserID == userID); + + // delete all bookmarks of user + BookmarkCollection bookmarkDeleter = new BookmarkCollection(); + trans.Add(bookmarkDeleter); + // delete all bookmarks for this user directly from the DB using the following filter. + bookmarkDeleter.DeleteMulti(BookmarkFields.UserID == userID); + + // delete all audit data + AuditDataCoreCollection auditDataDeleter = new AuditDataCoreCollection(); + // first fetch it, then delete all entities from the collection, as the audit data is in an inheritance hierarchy of TargetPerEntity which can't + // be deleted directly from the db. + trans.Add(auditDataDeleter); + auditDataDeleter.GetMulti(AuditDataCoreFields.UserID == userID); + auditDataDeleter.DeleteMulti(); + + // set IP bans set by this user to userid 0 + IPBanEntity ipbanUpdater = new IPBanEntity(); + ipbanUpdater.IPBanSetByUserID = 0; + IPBanCollection ipBans = new IPBanCollection(); + trans.Add(ipBans); + ipBans.UpdateMulti(ipbanUpdater, (IPBanFields.IPBanSetByUserID == userID)); + + // delete threadsubscriptions + ThreadSubscriptionCollection threadSubscriptionsDeleter = new ThreadSubscriptionCollection(); + trans.Add(threadSubscriptionsDeleter); + threadSubscriptionsDeleter.DeleteMulti(ThreadSubscriptionFields.UserID == userID); + + // remove supportqueuethread claims + SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); + trans.Add(supportQueueThreads); + supportQueueThreads.DeleteMulti(SupportQueueThreadFields.ClaimedByUserID == userID); + + // set all placed in queue references to userid 0, so the threads stay in the queues. + SupportQueueThreadEntity supportQueueThreadUpdater = new SupportQueueThreadEntity(); + supportQueueThreadUpdater.PlacedInQueueByUserID=0; + supportQueueThreads.UpdateMulti(supportQueueThreadUpdater, (SupportQueueThreadFields.PlacedInQueueByUserID == userID)); + + // now delete the actual user entity + trans.Add(toDelete); + toDelete.Delete(); + + // all done + trans.Commit(); + return true; + } + catch + { + trans.Rollback(); + throw; + } + finally + { + trans.Dispose(); + } + } + + + /// + /// Removes the threads with threadid in the arraylist passed in from the bookmarks + /// + /// Thread I ds to remove. + /// user for whom these bookmarks have to be deleted + public static void RemoveBookmarks(ArrayList threadIDsToRemove, int userID) + { + // create the filter to use in the direct delete action on the bookmarks entities + PredicateExpression filter = new PredicateExpression(); + filter.Add(BookmarkFields.ThreadID == threadIDsToRemove); + filter.AddWithAnd(BookmarkFields.UserID == userID); + + BookmarkCollection bookmarks = new BookmarkCollection(); + // delete the bookmarks matching the filter directly from the database. + bookmarks.DeleteMulti(filter); + } + + + /// + /// Removes the single bookmark passed in + /// + /// Thread ID. + /// User ID. + /// + public static void RemoveSingleBookmark(int threadID, int userID) + { + PredicateExpression filter = new PredicateExpression(BookmarkFields.ThreadID == threadID); + filter.AddWithAnd(BookmarkFields.UserID == userID); + BookmarkCollection bookmarks = new BookmarkCollection(); + // delete the bookmark directly from the database, no need for fetching it first. + bookmarks.DeleteMulti(filter); + } + + + /// + /// Resets the user's Password by generating a new random password which is mailed to + /// the emailaddress specified. Will fail if the nickname doesn't exist or the emailaddress + /// doesn't match with the specified emailaddress of the nickname in the database. + /// + /// Nickname of user which password should be reset + /// Emailaddress of user + /// The email template. + /// The email data. + /// true if succeed, false otherwise + /// Throws NickNameNotFoundException when the nickname isn't found. + /// Throws EmailAddressDoesntMatchException when the emailaddress of the nickname isn't matching + /// with the emailaddress specified. + public static bool ResetPassword(string nickName, string emailAddress, string emailTemplate, Dictionary emailData) + { + UserEntity user = new UserEntity(); + // fetch the user using the unique constraint fetch logic on nickname + bool fetchResult = user.FetchUsingUCNickName(nickName); + if(!fetchResult) + { + // not found + throw new NickNameNotFoundException("Nickname: '" + nickName + "' not found"); + } + + // check emailaddress + if(user.EmailAddress.ToLowerInvariant() != emailAddress.ToLowerInvariant()) + { + // no match + throw new EmailAddressDoesntMatchException("Emailaddress '" + emailAddress + "' doesn't match."); + } + + // does match, reset the password + string newPassword = HnDGeneralUtils.GenerateRandomPassword(); + + // hash the password with an MD5 hash and store that hashed value into the database. + user.Password = HnDGeneralUtils.CreateMD5HashedBase64String(newPassword); + + // store it + bool result = user.Save(); + if(result) + { + // mail it + result = HnDGeneralUtils.EmailPassword(newPassword, emailAddress, emailTemplate, emailData); + } + + //done + return result; + } + + + /// + /// Updates the given user's profile data using the values of the properties of this class. + /// + /// The user ID. + /// The date of birth. + /// The email address. + /// flag to signal if the emailaddress is visible for everyone or not + /// The icon URL. + /// The location. + /// The occupation. + /// The password. + /// The signature. + /// The website. + /// The user title ID. + /// The parser data. + /// Default value when user creates new threads. + /// Messages per page to display + /// true if succeeded, false otherwise + public static bool UpdateUserProfile(int userID, DateTime? dateOfBirth, string emailAddress, bool emailAddressIsPublic, string iconURL, + string location, string occupation, string password, string signature, string website, int userTitleID, ParserData parserData, + bool autoSubscribeThreads, short defaultMessagesPerPage) + { + UserEntity user = UserGuiHelper.GetUser(userID); + if (user == null) + { + // not found + return false; + } + + user.DateOfBirth = dateOfBirth; + user.EmailAddress = emailAddress; + user.EmailAddressIsPublic = emailAddressIsPublic; + user.IconURL = iconURL; + user.Location = location; + user.Occupation = occupation; + user.UserTitleID = userTitleID; + + if(!string.IsNullOrEmpty(password)) + { + user.Password = HnDGeneralUtils.CreateMD5HashedBase64String(password); + } + user.Signature = signature; + if(!string.IsNullOrEmpty(signature)) + { + user.SignatureAsHTML = TextParser.TransformSignatureUBBStringToHTML(signature, parserData); + } + else + { + user.SignatureAsHTML = ""; + } + + user.Website = website; + + //Preferences + user.AutoSubscribeToThread = autoSubscribeThreads; + user.DefaultNumberOfMessagesPerPage = defaultMessagesPerPage; + + // first encode fields which could lead to cross-site-scripting attacks + EncodeUserTextFields(user); + + // Update the record + return user.Save(true); + } + + + /// + /// Registers a new user, using the properties of this class. + /// + /// Name of the nick. + /// The date of birth. + /// The email address. + /// flag to signal if the emailaddress is visible for everyone or not + /// The icon URL. + /// The ip number. + /// The location. + /// The occupation. + /// The signature. + /// The website. + /// The email template path. + /// The email data. + /// Default value when user creates new threads. + /// Messages per page to display + /// + /// UserID of new user or 0 if registration failed. + /// + public static int RegisterNewUser(string nickName, DateTime? dateOfBirth, string emailAddress, bool emailAddressIsPublic, string iconURL, + string ipNumber, string location, string occupation, string signature, string website, string emailTemplatePath, Dictionary emailData, ParserData parserData, + bool autoSubscribeThreads, short defaultMessagesPerPage) + { + UserEntity newUser = new UserEntity(); + + // initialize objects + newUser.AmountOfPostings = 0; + newUser.DateOfBirth = dateOfBirth; + newUser.EmailAddress = emailAddress; + newUser.EmailAddressIsPublic = emailAddressIsPublic; + newUser.IPNumber = ipNumber; + newUser.IconURL = iconURL; + newUser.IsBanned = false; + newUser.JoinDate = DateTime.Now; + newUser.Location = location; + newUser.NickName = nickName; + newUser.Occupation = occupation; + newUser.Signature = signature; + newUser.Website = website; + string password = HnDGeneralUtils.GenerateRandomPassword(); + newUser.Password = HnDGeneralUtils.CreateMD5HashedBase64String(password); + + //Preferences + newUser.AutoSubscribeToThread = autoSubscribeThreads; + newUser.DefaultNumberOfMessagesPerPage = defaultMessagesPerPage; + + if(!string.IsNullOrEmpty(signature)) + { + newUser.SignatureAsHTML = TextParser.TransformSignatureUBBStringToHTML(signature, parserData); + } + else + { + newUser.SignatureAsHTML = ""; + } + //Fetch the SystemDataEntity to use the "DefaultUserTitleNewUser" as the user title & the "DefaultRoleNewUser" + // as the roleID of the newly created RoleUserEntity. + SystemDataEntity systemData = SystemGuiHelper.GetSystemSettings(); + newUser.UserTitleID = systemData.DefaultUserTitleNewUser; + + RoleUserEntity roleUser = new RoleUserEntity(); + roleUser.RoleID = systemData.DefaultRoleNewUser; + roleUser.User = newUser; + + // first encode fields which could lead to cross-site-scripting attacks + EncodeUserTextFields(newUser); + + // now save the new user entity and the new RoleUser entity recursively in one go. This will create a transaction for us + // under the hood so we don't have to do that ourselves. + if (newUser.Save(true)) + { + // all ok, Email the password + bool result = HnDGeneralUtils.EmailPassword(password, emailAddress, emailTemplatePath, emailData); + + } + + return newUser.UserID; + } + + + /// + /// Encodes some of the user text fields in the passed in entity. Encoding is done here so the data is HtmlEncoded when it's saved into the database. + /// This routine is used in code to store data. It's stored encoded so viewing logic isn't relying on the encoding code inside the page, which might be + /// absent and which then would create a potential cross-site scripting error. + /// + /// To encode. + /// Fields which are filled in by the user are encoded using HtmlEncoding. The signature is parsed by the UBB parser and therefore already + /// is free from potential scripting code as tag markers are already converted to html encoded characters. + private static void EncodeUserTextFields(UserEntity toEncode) + { + toEncode.EmailAddress = HttpUtility.HtmlEncode(toEncode.EmailAddress); + toEncode.Occupation = HttpUtility.HtmlEncode(toEncode.Occupation); + toEncode.Location = HttpUtility.HtmlEncode(toEncode.Location); + toEncode.Website = HttpUtility.HtmlEncode(toEncode.Website); + toEncode.IconURL = HttpUtility.HtmlEncode(toEncode.IconURL); + } + } +} diff --git a/DAL/App.config b/DAL/App.config new file mode 100644 index 0000000..60d30e9 --- /dev/null +++ b/DAL/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/DAL/AssemblyInfo.cs b/DAL/AssemblyInfo.cs new file mode 100644 index 0000000..029dfd2 --- /dev/null +++ b/DAL/AssemblyInfo.cs @@ -0,0 +1,77 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("SD.HnD.DAL")] +[assembly: AssemblyDescription("HnD's DAL")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Solutions Design")] +[assembly: AssemblyProduct("HnD, a .NET 2.0 Forum system using LLBLGen Pro")] +[assembly: AssemblyCopyright("(c)2002-2006 Solutions Design")] +[assembly: AssemblyTrademark("HnD, LLBLGen and LLBLGen Pro are trademarks of Solutions Design.")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/DAL/ClassExtensions/MessagesInThreadTypedListExtension.cs b/DAL/ClassExtensions/MessagesInThreadTypedListExtension.cs new file mode 100644 index 0000000..e206c12 --- /dev/null +++ b/DAL/ClassExtensions/MessagesInThreadTypedListExtension.cs @@ -0,0 +1,115 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections.Generic; +using System.Text; +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.HelperClasses; +using System.Data; + +namespace SD.HnD.DAL.TypedListClasses +{ + /// + /// Extension class which extends the typedlist MessagesInThreadTypedList and adds a scalar query expression column to the typedlist. + /// + public partial class MessagesInThreadTypedList + { + #region Class Member Declarations + private DataColumn _columnAmountOfAttachments; + #endregion + + /// + /// Called when the typedlist's resultset has been build. This is the spot to add additional columns to the typedlist in code. + /// We do this in code because we can't add a scalar query expression in the typedlist designer. + /// + /// The typedlist resultset fields. + protected override void OnResultsetBuilt(IEntityFields fields) + { + // expand the fields with 1 slot, so we can add our scalar query expression to that slot + int index = fields.Count; + fields.Expand(1); + // add a scalar query expression to the list of fields in the typedlist. The scalar query expression + // performs a SELECT COUNT(AttachmentID) FROM Attachments WHERE MessageID = Message.MessageID + // query. Pass a type to the CTor as well, as otherwise the type isn't properly determinable. + fields.DefineField(new EntityField("AmountOfAttachments", + new ScalarQueryExpression(AttachmentFields.AttachmentID.SetAggregateFunction(AggregateFunction.Count), + (AttachmentFields.MessageID == MessageFields.MessageID)), typeof(int)), index); + + // done + base.OnResultsetBuilt(fields); + } + + + /// + /// Called when InitClass of the typedlist ended. + /// + protected override void OnInitialized() + { + _columnAmountOfAttachments = new DataColumn("AmountOfAttachments", typeof(int), null, MappingType.Element); + _columnAmountOfAttachments.ReadOnly = true; + this.Columns.Add(_columnAmountOfAttachments); + base.OnInitialized(); + } + + + #region Class Property Declarations + /// + /// Gets the amount of attachments column. + /// + /// The amount of attachments column. + internal DataColumn AmountOfAttachmentsColumn + { + get { return _columnAmountOfAttachments; } + } + #endregion + } + + + + /// + /// Extension class for the row class of the MessagesInThread typedlist. + /// + public partial class MessagesInThreadRow + { + /// Gets / sets the value of the TypedList field AmountOfAttachments

+ ///
+ /// Mapped on: the scalar query expression for retrieving the # of attachments for each message + public int AmountOfAttachments + { + get + { + if(IsAmountOfAttachmentsNull()) + { + return 0; + } + else + { + return (int)this[_parent.AmountOfAttachmentsColumn]; + } + } + } + + /// Returns true if the TypedList field MessageID is NULL, false otherwise. + public bool IsAmountOfAttachmentsNull() + { + return IsNull(_parent.MessageIDColumn); + } + } +} diff --git a/DAL/CollectionClasses/ActionRightCollection.cs b/DAL/CollectionClasses/ActionRightCollection.cs new file mode 100644 index 0000000..51887fc --- /dev/null +++ b/DAL/CollectionClasses/ActionRightCollection.cs @@ -0,0 +1,258 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of ActionRightEntity objects. + [Serializable] + public partial class ActionRightCollection : EntityCollectionBase + { + /// CTor + public ActionRightCollection():base(new ActionRightEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public ActionRightCollection(IList initialContents):base(new ActionRightEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public ActionRightCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected ActionRightCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + + /// Retrieves in this ActionRightCollection object all ActionRightEntity objects which are related via a Relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingSystemRightAssignedToRoles(IEntity roleInstance) + { + return GetMultiManyToManyUsingSystemRightAssignedToRoles(roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this ActionRightCollection object all ActionRightEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingSystemRightAssignedToRoles(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingSystemRightAssignedToRoles(roleInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this ActionRightCollection object all ActionRightEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingSystemRightAssignedToRoles(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ActionRightDAO dao = DAOFactory.CreateActionRightDAO(); + return dao.GetMultiUsingSystemRightAssignedToRoles(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, roleInstance, pageNumber, pageSize); + } + + /// Retrieves in this ActionRightCollection object all ActionRightEntity objects which are related via a Relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingSystemRightAssignedToRoles(IEntity roleInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingSystemRightAssignedToRoles(roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this ActionRightCollection object all ActionRightEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingSystemRightAssignedToRoles(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ActionRightDAO dao = DAOFactory.CreateActionRightDAO(); + return dao.GetMultiUsingSystemRightAssignedToRoles(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, roleInstance, prefetchPathToUse); + } + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + ActionRightDAO dao = DAOFactory.CreateActionRightDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ActionRightFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(ActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + ActionRightDAO dao = DAOFactory.CreateActionRightDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateActionRightDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/AttachmentCollection.cs b/DAL/CollectionClasses/AttachmentCollection.cs new file mode 100644 index 0000000..1150ec8 --- /dev/null +++ b/DAL/CollectionClasses/AttachmentCollection.cs @@ -0,0 +1,270 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of AttachmentEntity objects. + [Serializable] + public partial class AttachmentCollection : EntityCollectionBase + { + /// CTor + public AttachmentCollection():base(new AttachmentEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public AttachmentCollection(IList initialContents):base(new AttachmentEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public AttachmentCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected AttachmentCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this AttachmentCollection object all AttachmentEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity belongsToMessageInstance) + { + return GetMultiManyToOne(belongsToMessageInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this AttachmentCollection object all AttachmentEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity belongsToMessageInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(belongsToMessageInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this AttachmentCollection object all AttachmentEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity belongsToMessageInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(belongsToMessageInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this AttachmentCollection object all AttachmentEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity belongsToMessageInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (belongsToMessageInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + AttachmentDAO dao = DAOFactory.CreateAttachmentDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, belongsToMessageInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all Attachment entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity belongsToMessageInstance) + { + AttachmentDAO dao = DAOFactory.CreateAttachmentDAO(); + return dao.DeleteMulti(base.Transaction, belongsToMessageInstance); + } + + /// Updates in the persistent storage all Attachment entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// AttachmentEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(AttachmentEntity entityWithNewValues, IEntity belongsToMessageInstance) + { + AttachmentDAO dao = DAOFactory.CreateAttachmentDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, belongsToMessageInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + AttachmentDAO dao = DAOFactory.CreateAttachmentDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AttachmentFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AttachmentFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AttachmentFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AttachmentFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(AttachmentFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + AttachmentDAO dao = DAOFactory.CreateAttachmentDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAttachmentDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/AuditActionCollection.cs b/DAL/CollectionClasses/AuditActionCollection.cs new file mode 100644 index 0000000..9c134a4 --- /dev/null +++ b/DAL/CollectionClasses/AuditActionCollection.cs @@ -0,0 +1,258 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of AuditActionEntity objects. + [Serializable] + public partial class AuditActionCollection : EntityCollectionBase + { + /// CTor + public AuditActionCollection():base(new AuditActionEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public AuditActionCollection(IList initialContents):base(new AuditActionEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public AuditActionCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected AuditActionCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + + /// Retrieves in this AuditActionCollection object all AuditActionEntity objects which are related via a Relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingRolesWithAuditAction(IEntity roleInstance) + { + return GetMultiManyToManyUsingRolesWithAuditAction(roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this AuditActionCollection object all AuditActionEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingRolesWithAuditAction(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingRolesWithAuditAction(roleInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this AuditActionCollection object all AuditActionEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingRolesWithAuditAction(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + AuditActionDAO dao = DAOFactory.CreateAuditActionDAO(); + return dao.GetMultiUsingRolesWithAuditAction(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, roleInstance, pageNumber, pageSize); + } + + /// Retrieves in this AuditActionCollection object all AuditActionEntity objects which are related via a Relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingRolesWithAuditAction(IEntity roleInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingRolesWithAuditAction(roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this AuditActionCollection object all AuditActionEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingRolesWithAuditAction(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + AuditActionDAO dao = DAOFactory.CreateAuditActionDAO(); + return dao.GetMultiUsingRolesWithAuditAction(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, roleInstance, prefetchPathToUse); + } + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + AuditActionDAO dao = DAOFactory.CreateAuditActionDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AuditActionFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AuditActionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AuditActionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AuditActionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(AuditActionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + AuditActionDAO dao = DAOFactory.CreateAuditActionDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAuditActionDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/AuditDataCoreCollection.cs b/DAL/CollectionClasses/AuditDataCoreCollection.cs new file mode 100644 index 0000000..0f601b7 --- /dev/null +++ b/DAL/CollectionClasses/AuditDataCoreCollection.cs @@ -0,0 +1,293 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of AuditDataCoreEntity objects. + [Serializable] + public partial class AuditDataCoreCollection : EntityCollectionBase + { + /// CTor + public AuditDataCoreCollection():base(new AuditDataCoreEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public AuditDataCoreCollection(IList initialContents):base(new AuditDataCoreEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public AuditDataCoreCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected AuditDataCoreCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this AuditDataCoreCollection object all AuditDataCoreEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity userAuditedInstance) + { + return GetMultiManyToOne(auditActionInstance, userAuditedInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this AuditDataCoreCollection object all AuditDataCoreEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity userAuditedInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(auditActionInstance, userAuditedInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this AuditDataCoreCollection object all AuditDataCoreEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity userAuditedInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(auditActionInstance, userAuditedInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this AuditDataCoreCollection object all AuditDataCoreEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity auditActionInstance, IEntity userAuditedInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (auditActionInstance!=null); + validParameters |= (userAuditedInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + AuditDataCoreDAO dao = DAOFactory.CreateAuditDataCoreDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, auditActionInstance, userAuditedInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all AuditDataCore entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity auditActionInstance, IEntity userAuditedInstance) + { + AuditDataCoreDAO dao = DAOFactory.CreateAuditDataCoreDAO(); + return dao.DeleteMulti(base.Transaction, auditActionInstance, userAuditedInstance); + } + + /// Updates in the persistent storage all AuditDataCore entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// AuditDataCoreEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(AuditDataCoreEntity entityWithNewValues, IEntity auditActionInstance, IEntity userAuditedInstance) + { + AuditDataCoreDAO dao = DAOFactory.CreateAuditDataCoreDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, auditActionInstance, userAuditedInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + AuditDataCoreDAO dao = DAOFactory.CreateAuditDataCoreDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// Deletes from the persistent storage all AuditDataCore entities which match with the specified filter, formulated in the predicate or predicate expression definition. + /// A predicate or predicate expression which should be used as filter for the entities to delete. Can be null, which will result in a query removing all AuditDataCore entities from the persistent storage + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public override int DeleteMulti(IPredicate deleteFilter) + { + throw new NotSupportedException("This method isn't supported for this entity"); + } + + /// Deletes from the persistent storage all AuditDataCore entities which match with the specified filter, formulated in the predicate or predicate expression definition. + /// A predicate or predicate expression which should be used as filter for the entities to delete. + /// The set of relations to walk to construct the total query. + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public override int DeleteMulti(IPredicate deleteFilter, IRelationCollection relations) + { + throw new NotSupportedException("This method isn't supported for this entity"); + } + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AuditDataCoreFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AuditDataCoreFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AuditDataCoreFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AuditDataCoreFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(AuditDataCoreFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + AuditDataCoreDAO dao = DAOFactory.CreateAuditDataCoreDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAuditDataCoreDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/AuditDataMessageRelatedCollection.cs b/DAL/CollectionClasses/AuditDataMessageRelatedCollection.cs new file mode 100644 index 0000000..9420cc4 --- /dev/null +++ b/DAL/CollectionClasses/AuditDataMessageRelatedCollection.cs @@ -0,0 +1,300 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of AuditDataMessageRelatedEntity objects. + [Serializable] + public partial class AuditDataMessageRelatedCollection : EntityCollectionBase + { + /// CTor + public AuditDataMessageRelatedCollection():base(new AuditDataMessageRelatedEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public AuditDataMessageRelatedCollection(IList initialContents):base(new AuditDataMessageRelatedEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public AuditDataMessageRelatedCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected AuditDataMessageRelatedCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this AuditDataMessageRelatedCollection object all AuditDataMessageRelatedEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance) + { + return GetMultiManyToOne(auditActionInstance, messageInstance, userAuditedInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this AuditDataMessageRelatedCollection object all AuditDataMessageRelatedEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(auditActionInstance, messageInstance, userAuditedInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this AuditDataMessageRelatedCollection object all AuditDataMessageRelatedEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(auditActionInstance, messageInstance, userAuditedInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this AuditDataMessageRelatedCollection object all AuditDataMessageRelatedEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (auditActionInstance!=null); + validParameters |= (messageInstance!=null); + validParameters |= (userAuditedInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + AuditDataMessageRelatedDAO dao = DAOFactory.CreateAuditDataMessageRelatedDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, auditActionInstance, messageInstance, userAuditedInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all AuditDataMessageRelated entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance) + { + AuditDataMessageRelatedDAO dao = DAOFactory.CreateAuditDataMessageRelatedDAO(); + return dao.DeleteMulti(base.Transaction, auditActionInstance, messageInstance, userAuditedInstance); + } + + /// Updates in the persistent storage all AuditDataMessageRelated entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// AuditDataMessageRelatedEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(AuditDataMessageRelatedEntity entityWithNewValues, IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance) + { + AuditDataMessageRelatedDAO dao = DAOFactory.CreateAuditDataMessageRelatedDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, auditActionInstance, messageInstance, userAuditedInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + AuditDataMessageRelatedDAO dao = DAOFactory.CreateAuditDataMessageRelatedDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// Deletes from the persistent storage all AuditDataMessageRelated entities which match with the specified filter, formulated in the predicate or predicate expression definition. + /// A predicate or predicate expression which should be used as filter for the entities to delete. Can be null, which will result in a query removing all AuditDataMessageRelated entities from the persistent storage + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public override int DeleteMulti(IPredicate deleteFilter) + { + throw new NotSupportedException("This method isn't supported for this entity"); + } + + /// Deletes from the persistent storage all AuditDataMessageRelated entities which match with the specified filter, formulated in the predicate or predicate expression definition. + /// A predicate or predicate expression which should be used as filter for the entities to delete. + /// The set of relations to walk to construct the total query. + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public override int DeleteMulti(IPredicate deleteFilter, IRelationCollection relations) + { + throw new NotSupportedException("This method isn't supported for this entity"); + } + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AuditDataMessageRelatedFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AuditDataMessageRelatedFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AuditDataMessageRelatedFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AuditDataMessageRelatedFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(AuditDataMessageRelatedFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + AuditDataMessageRelatedDAO dao = DAOFactory.CreateAuditDataMessageRelatedDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAuditDataMessageRelatedDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/AuditDataThreadRelatedCollection.cs b/DAL/CollectionClasses/AuditDataThreadRelatedCollection.cs new file mode 100644 index 0000000..479274f --- /dev/null +++ b/DAL/CollectionClasses/AuditDataThreadRelatedCollection.cs @@ -0,0 +1,300 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of AuditDataThreadRelatedEntity objects. + [Serializable] + public partial class AuditDataThreadRelatedCollection : EntityCollectionBase + { + /// CTor + public AuditDataThreadRelatedCollection():base(new AuditDataThreadRelatedEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public AuditDataThreadRelatedCollection(IList initialContents):base(new AuditDataThreadRelatedEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public AuditDataThreadRelatedCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected AuditDataThreadRelatedCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this AuditDataThreadRelatedCollection object all AuditDataThreadRelatedEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance) + { + return GetMultiManyToOne(auditActionInstance, threadInstance, userAuditedInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this AuditDataThreadRelatedCollection object all AuditDataThreadRelatedEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(auditActionInstance, threadInstance, userAuditedInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this AuditDataThreadRelatedCollection object all AuditDataThreadRelatedEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(auditActionInstance, threadInstance, userAuditedInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this AuditDataThreadRelatedCollection object all AuditDataThreadRelatedEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (auditActionInstance!=null); + validParameters |= (threadInstance!=null); + validParameters |= (userAuditedInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + AuditDataThreadRelatedDAO dao = DAOFactory.CreateAuditDataThreadRelatedDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, auditActionInstance, threadInstance, userAuditedInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all AuditDataThreadRelated entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance) + { + AuditDataThreadRelatedDAO dao = DAOFactory.CreateAuditDataThreadRelatedDAO(); + return dao.DeleteMulti(base.Transaction, auditActionInstance, threadInstance, userAuditedInstance); + } + + /// Updates in the persistent storage all AuditDataThreadRelated entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// AuditDataThreadRelatedEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(AuditDataThreadRelatedEntity entityWithNewValues, IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance) + { + AuditDataThreadRelatedDAO dao = DAOFactory.CreateAuditDataThreadRelatedDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, auditActionInstance, threadInstance, userAuditedInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + AuditDataThreadRelatedDAO dao = DAOFactory.CreateAuditDataThreadRelatedDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// Deletes from the persistent storage all AuditDataThreadRelated entities which match with the specified filter, formulated in the predicate or predicate expression definition. + /// A predicate or predicate expression which should be used as filter for the entities to delete. Can be null, which will result in a query removing all AuditDataThreadRelated entities from the persistent storage + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public override int DeleteMulti(IPredicate deleteFilter) + { + throw new NotSupportedException("This method isn't supported for this entity"); + } + + /// Deletes from the persistent storage all AuditDataThreadRelated entities which match with the specified filter, formulated in the predicate or predicate expression definition. + /// A predicate or predicate expression which should be used as filter for the entities to delete. + /// The set of relations to walk to construct the total query. + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public override int DeleteMulti(IPredicate deleteFilter, IRelationCollection relations) + { + throw new NotSupportedException("This method isn't supported for this entity"); + } + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AuditDataThreadRelatedFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(AuditDataThreadRelatedFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AuditDataThreadRelatedFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(AuditDataThreadRelatedFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(AuditDataThreadRelatedFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + AuditDataThreadRelatedDAO dao = DAOFactory.CreateAuditDataThreadRelatedDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAuditDataThreadRelatedDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/BookmarkCollection.cs b/DAL/CollectionClasses/BookmarkCollection.cs new file mode 100644 index 0000000..af7ce86 --- /dev/null +++ b/DAL/CollectionClasses/BookmarkCollection.cs @@ -0,0 +1,277 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of BookmarkEntity objects. + [Serializable] + public partial class BookmarkCollection : EntityCollectionBase + { + /// CTor + public BookmarkCollection():base(new BookmarkEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public BookmarkCollection(IList initialContents):base(new BookmarkEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public BookmarkCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected BookmarkCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this BookmarkCollection object all BookmarkEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to return + /// UserEntity instance to use as a filter for the BookmarkEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity userInstance) + { + return GetMultiManyToOne(threadInstance, userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this BookmarkCollection object all BookmarkEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to return + /// UserEntity instance to use as a filter for the BookmarkEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity userInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(threadInstance, userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this BookmarkCollection object all BookmarkEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to return + /// UserEntity instance to use as a filter for the BookmarkEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(threadInstance, userInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this BookmarkCollection object all BookmarkEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to return + /// UserEntity instance to use as a filter for the BookmarkEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity threadInstance, IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (threadInstance!=null); + validParameters |= (userInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + BookmarkDAO dao = DAOFactory.CreateBookmarkDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, threadInstance, userInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all Bookmark entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to return + /// UserEntity instance to use as a filter for the BookmarkEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity threadInstance, IEntity userInstance) + { + BookmarkDAO dao = DAOFactory.CreateBookmarkDAO(); + return dao.DeleteMulti(base.Transaction, threadInstance, userInstance); + } + + /// Updates in the persistent storage all Bookmark entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// BookmarkEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to return + /// UserEntity instance to use as a filter for the BookmarkEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(BookmarkEntity entityWithNewValues, IEntity threadInstance, IEntity userInstance) + { + BookmarkDAO dao = DAOFactory.CreateBookmarkDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, threadInstance, userInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + BookmarkDAO dao = DAOFactory.CreateBookmarkDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(BookmarkFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(BookmarkFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(BookmarkFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(BookmarkFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(BookmarkFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + BookmarkDAO dao = DAOFactory.CreateBookmarkDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateBookmarkDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/ForumCollection.cs b/DAL/CollectionClasses/ForumCollection.cs new file mode 100644 index 0000000..cbc1f81 --- /dev/null +++ b/DAL/CollectionClasses/ForumCollection.cs @@ -0,0 +1,341 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of ForumEntity objects. + [Serializable] + public partial class ForumCollection : EntityCollectionBase + { + /// CTor + public ForumCollection():base(new ForumEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public ForumCollection(IList initialContents):base(new ForumEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public ForumCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected ForumCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this ForumCollection object all ForumEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// SectionEntity instance to use as a filter for the ForumEntity objects to return + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity sectionInstance, IEntity defaultSupportQueueInstance) + { + return GetMultiManyToOne(sectionInstance, defaultSupportQueueInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this ForumCollection object all ForumEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// SectionEntity instance to use as a filter for the ForumEntity objects to return + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity sectionInstance, IEntity defaultSupportQueueInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(sectionInstance, defaultSupportQueueInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this ForumCollection object all ForumEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// SectionEntity instance to use as a filter for the ForumEntity objects to return + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity sectionInstance, IEntity defaultSupportQueueInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(sectionInstance, defaultSupportQueueInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this ForumCollection object all ForumEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// SectionEntity instance to use as a filter for the ForumEntity objects to return + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity sectionInstance, IEntity defaultSupportQueueInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (sectionInstance!=null); + validParameters |= (defaultSupportQueueInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ForumDAO dao = DAOFactory.CreateForumDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, sectionInstance, defaultSupportQueueInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all Forum entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// SectionEntity instance to use as a filter for the ForumEntity objects to return + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity sectionInstance, IEntity defaultSupportQueueInstance) + { + ForumDAO dao = DAOFactory.CreateForumDAO(); + return dao.DeleteMulti(base.Transaction, sectionInstance, defaultSupportQueueInstance); + } + + /// Updates in the persistent storage all Forum entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// ForumEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// SectionEntity instance to use as a filter for the ForumEntity objects to return + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(ForumEntity entityWithNewValues, IEntity sectionInstance, IEntity defaultSupportQueueInstance) + { + ForumDAO dao = DAOFactory.CreateForumDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, sectionInstance, defaultSupportQueueInstance); + } + + /// Retrieves in this ForumCollection object all ForumEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoStartedThreads(IEntity userInstance) + { + return GetMultiManyToManyUsingUsersWhoStartedThreads(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this ForumCollection object all ForumEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoStartedThreads(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingUsersWhoStartedThreads(userInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this ForumCollection object all ForumEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingUsersWhoStartedThreads(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ForumDAO dao = DAOFactory.CreateForumDAO(); + return dao.GetMultiUsingUsersWhoStartedThreads(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, pageNumber, pageSize); + } + + /// Retrieves in this ForumCollection object all ForumEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoStartedThreads(IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingUsersWhoStartedThreads(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this ForumCollection object all ForumEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoStartedThreads(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ForumDAO dao = DAOFactory.CreateForumDAO(); + return dao.GetMultiUsingUsersWhoStartedThreads(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, prefetchPathToUse); + } + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + ForumDAO dao = DAOFactory.CreateForumDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ForumFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ForumFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ForumFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ForumFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(ForumFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + ForumDAO dao = DAOFactory.CreateForumDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateForumDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/ForumRoleForumActionRightCollection.cs b/DAL/CollectionClasses/ForumRoleForumActionRightCollection.cs new file mode 100644 index 0000000..447042a --- /dev/null +++ b/DAL/CollectionClasses/ForumRoleForumActionRightCollection.cs @@ -0,0 +1,284 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of ForumRoleForumActionRightEntity objects. + [Serializable] + public partial class ForumRoleForumActionRightCollection : EntityCollectionBase + { + /// CTor + public ForumRoleForumActionRightCollection():base(new ForumRoleForumActionRightEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public ForumRoleForumActionRightCollection(IList initialContents):base(new ForumRoleForumActionRightEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public ForumRoleForumActionRightCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected ForumRoleForumActionRightCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this ForumRoleForumActionRightCollection object all ForumRoleForumActionRightEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance) + { + return GetMultiManyToOne(actionRightInstance, forumInstance, roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this ForumRoleForumActionRightCollection object all ForumRoleForumActionRightEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(actionRightInstance, forumInstance, roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this ForumRoleForumActionRightCollection object all ForumRoleForumActionRightEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(actionRightInstance, forumInstance, roleInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this ForumRoleForumActionRightCollection object all ForumRoleForumActionRightEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (actionRightInstance!=null); + validParameters |= (forumInstance!=null); + validParameters |= (roleInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ForumRoleForumActionRightDAO dao = DAOFactory.CreateForumRoleForumActionRightDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, actionRightInstance, forumInstance, roleInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all ForumRoleForumActionRight entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance) + { + ForumRoleForumActionRightDAO dao = DAOFactory.CreateForumRoleForumActionRightDAO(); + return dao.DeleteMulti(base.Transaction, actionRightInstance, forumInstance, roleInstance); + } + + /// Updates in the persistent storage all ForumRoleForumActionRight entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// ForumRoleForumActionRightEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(ForumRoleForumActionRightEntity entityWithNewValues, IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance) + { + ForumRoleForumActionRightDAO dao = DAOFactory.CreateForumRoleForumActionRightDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, actionRightInstance, forumInstance, roleInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + ForumRoleForumActionRightDAO dao = DAOFactory.CreateForumRoleForumActionRightDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ForumRoleForumActionRightFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ForumRoleForumActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ForumRoleForumActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ForumRoleForumActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(ForumRoleForumActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + ForumRoleForumActionRightDAO dao = DAOFactory.CreateForumRoleForumActionRightDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateForumRoleForumActionRightDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/IPBanCollection.cs b/DAL/CollectionClasses/IPBanCollection.cs new file mode 100644 index 0000000..06e5aa2 --- /dev/null +++ b/DAL/CollectionClasses/IPBanCollection.cs @@ -0,0 +1,270 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of IPBanEntity objects. + [Serializable] + public partial class IPBanCollection : EntityCollectionBase + { + /// CTor + public IPBanCollection():base(new IPBanEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public IPBanCollection(IList initialContents):base(new IPBanEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public IPBanCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected IPBanCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this IPBanCollection object all IPBanEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// UserEntity instance to use as a filter for the IPBanEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity setByUserInstance) + { + return GetMultiManyToOne(setByUserInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this IPBanCollection object all IPBanEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// UserEntity instance to use as a filter for the IPBanEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity setByUserInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(setByUserInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this IPBanCollection object all IPBanEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// UserEntity instance to use as a filter for the IPBanEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity setByUserInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(setByUserInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this IPBanCollection object all IPBanEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// UserEntity instance to use as a filter for the IPBanEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity setByUserInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (setByUserInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + IPBanDAO dao = DAOFactory.CreateIPBanDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, setByUserInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all IPBan entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// UserEntity instance to use as a filter for the IPBanEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity setByUserInstance) + { + IPBanDAO dao = DAOFactory.CreateIPBanDAO(); + return dao.DeleteMulti(base.Transaction, setByUserInstance); + } + + /// Updates in the persistent storage all IPBan entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// IPBanEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// UserEntity instance to use as a filter for the IPBanEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(IPBanEntity entityWithNewValues, IEntity setByUserInstance) + { + IPBanDAO dao = DAOFactory.CreateIPBanDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, setByUserInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + IPBanDAO dao = DAOFactory.CreateIPBanDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(IPBanFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(IPBanFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(IPBanFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(IPBanFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(IPBanFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + IPBanDAO dao = DAOFactory.CreateIPBanDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateIPBanDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/MessageCollection.cs b/DAL/CollectionClasses/MessageCollection.cs new file mode 100644 index 0000000..a351118 --- /dev/null +++ b/DAL/CollectionClasses/MessageCollection.cs @@ -0,0 +1,277 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of MessageEntity objects. + [Serializable] + public partial class MessageCollection : EntityCollectionBase + { + /// CTor + public MessageCollection():base(new MessageEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public MessageCollection(IList initialContents):base(new MessageEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public MessageCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected MessageCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this MessageCollection object all MessageEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the MessageEntity objects to return + /// UserEntity instance to use as a filter for the MessageEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity postedByUserInstance) + { + return GetMultiManyToOne(threadInstance, postedByUserInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this MessageCollection object all MessageEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the MessageEntity objects to return + /// UserEntity instance to use as a filter for the MessageEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity postedByUserInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(threadInstance, postedByUserInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this MessageCollection object all MessageEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the MessageEntity objects to return + /// UserEntity instance to use as a filter for the MessageEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity postedByUserInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(threadInstance, postedByUserInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this MessageCollection object all MessageEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the MessageEntity objects to return + /// UserEntity instance to use as a filter for the MessageEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity threadInstance, IEntity postedByUserInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (threadInstance!=null); + validParameters |= (postedByUserInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + MessageDAO dao = DAOFactory.CreateMessageDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, threadInstance, postedByUserInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all Message entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// ThreadEntity instance to use as a filter for the MessageEntity objects to return + /// UserEntity instance to use as a filter for the MessageEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity threadInstance, IEntity postedByUserInstance) + { + MessageDAO dao = DAOFactory.CreateMessageDAO(); + return dao.DeleteMulti(base.Transaction, threadInstance, postedByUserInstance); + } + + /// Updates in the persistent storage all Message entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// MessageEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// ThreadEntity instance to use as a filter for the MessageEntity objects to return + /// UserEntity instance to use as a filter for the MessageEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(MessageEntity entityWithNewValues, IEntity threadInstance, IEntity postedByUserInstance) + { + MessageDAO dao = DAOFactory.CreateMessageDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, threadInstance, postedByUserInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + MessageDAO dao = DAOFactory.CreateMessageDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(MessageFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(MessageFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(MessageFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(MessageFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(MessageFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + MessageDAO dao = DAOFactory.CreateMessageDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateMessageDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/RoleAuditActionCollection.cs b/DAL/CollectionClasses/RoleAuditActionCollection.cs new file mode 100644 index 0000000..0b10b0d --- /dev/null +++ b/DAL/CollectionClasses/RoleAuditActionCollection.cs @@ -0,0 +1,277 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of RoleAuditActionEntity objects. + [Serializable] + public partial class RoleAuditActionCollection : EntityCollectionBase + { + /// CTor + public RoleAuditActionCollection():base(new RoleAuditActionEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public RoleAuditActionCollection(IList initialContents):base(new RoleAuditActionEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public RoleAuditActionCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected RoleAuditActionCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this RoleAuditActionCollection object all RoleAuditActionEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity roleInstance) + { + return GetMultiManyToOne(auditActionInstance, roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this RoleAuditActionCollection object all RoleAuditActionEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity roleInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(auditActionInstance, roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this RoleAuditActionCollection object all RoleAuditActionEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity auditActionInstance, IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(auditActionInstance, roleInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this RoleAuditActionCollection object all RoleAuditActionEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity auditActionInstance, IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (auditActionInstance!=null); + validParameters |= (roleInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleAuditActionDAO dao = DAOFactory.CreateRoleAuditActionDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, auditActionInstance, roleInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all RoleAuditAction entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity auditActionInstance, IEntity roleInstance) + { + RoleAuditActionDAO dao = DAOFactory.CreateRoleAuditActionDAO(); + return dao.DeleteMulti(base.Transaction, auditActionInstance, roleInstance); + } + + /// Updates in the persistent storage all RoleAuditAction entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// RoleAuditActionEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(RoleAuditActionEntity entityWithNewValues, IEntity auditActionInstance, IEntity roleInstance) + { + RoleAuditActionDAO dao = DAOFactory.CreateRoleAuditActionDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, auditActionInstance, roleInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + RoleAuditActionDAO dao = DAOFactory.CreateRoleAuditActionDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(RoleAuditActionFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(RoleAuditActionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(RoleAuditActionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(RoleAuditActionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(RoleAuditActionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + RoleAuditActionDAO dao = DAOFactory.CreateRoleAuditActionDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateRoleAuditActionDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/RoleCollection.cs b/DAL/CollectionClasses/RoleCollection.cs new file mode 100644 index 0000000..0bec76b --- /dev/null +++ b/DAL/CollectionClasses/RoleCollection.cs @@ -0,0 +1,388 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of RoleEntity objects. + [Serializable] + public partial class RoleCollection : EntityCollectionBase + { + /// CTor + public RoleCollection():base(new RoleEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public RoleCollection(IList initialContents):base(new RoleEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public RoleCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected RoleCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a Relation of type 'm:n' with the passed in ActionRightEntity. + /// All current elements in the collection are removed from the collection. + /// ActionRightEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingAssignedSystemActionRights(IEntity actionRightInstance) + { + return GetMultiManyToManyUsingAssignedSystemActionRights(actionRightInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in ActionRightEntity. + /// All current elements in the collection are removed from the collection. + /// ActionRightEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingAssignedSystemActionRights(IEntity actionRightInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingAssignedSystemActionRights(actionRightInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in ActionRightEntity. + /// All current elements in the collection are removed from the collection. + /// ActionRightEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingAssignedSystemActionRights(IEntity actionRightInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleDAO dao = DAOFactory.CreateRoleDAO(); + return dao.GetMultiUsingAssignedSystemActionRights(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, actionRightInstance, pageNumber, pageSize); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a Relation of type 'm:n' with the passed in ActionRightEntity. + /// All current elements in the collection are removed from the collection. + /// ActionRightEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingAssignedSystemActionRights(IEntity actionRightInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingAssignedSystemActionRights(actionRightInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in ActionRightEntity. + /// All current elements in the collection are removed from the collection. + /// ActionRightEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingAssignedSystemActionRights(IEntity actionRightInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleDAO dao = DAOFactory.CreateRoleDAO(); + return dao.GetMultiUsingAssignedSystemActionRights(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, actionRightInstance, prefetchPathToUse); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a Relation of type 'm:n' with the passed in AuditActionEntity. + /// All current elements in the collection are removed from the collection. + /// AuditActionEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingAssignedAuditActions(IEntity auditActionInstance) + { + return GetMultiManyToManyUsingAssignedAuditActions(auditActionInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in AuditActionEntity. + /// All current elements in the collection are removed from the collection. + /// AuditActionEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingAssignedAuditActions(IEntity auditActionInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingAssignedAuditActions(auditActionInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in AuditActionEntity. + /// All current elements in the collection are removed from the collection. + /// AuditActionEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingAssignedAuditActions(IEntity auditActionInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleDAO dao = DAOFactory.CreateRoleDAO(); + return dao.GetMultiUsingAssignedAuditActions(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, auditActionInstance, pageNumber, pageSize); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a Relation of type 'm:n' with the passed in AuditActionEntity. + /// All current elements in the collection are removed from the collection. + /// AuditActionEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingAssignedAuditActions(IEntity auditActionInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingAssignedAuditActions(auditActionInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in AuditActionEntity. + /// All current elements in the collection are removed from the collection. + /// AuditActionEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingAssignedAuditActions(IEntity auditActionInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleDAO dao = DAOFactory.CreateRoleDAO(); + return dao.GetMultiUsingAssignedAuditActions(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, auditActionInstance, prefetchPathToUse); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsers(IEntity userInstance) + { + return GetMultiManyToManyUsingUsers(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsers(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingUsers(userInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingUsers(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleDAO dao = DAOFactory.CreateRoleDAO(); + return dao.GetMultiUsingUsers(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, pageNumber, pageSize); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsers(IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingUsers(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this RoleCollection object all RoleEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsers(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleDAO dao = DAOFactory.CreateRoleDAO(); + return dao.GetMultiUsingUsers(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, prefetchPathToUse); + } + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + RoleDAO dao = DAOFactory.CreateRoleDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(RoleFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(RoleFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(RoleFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(RoleFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(RoleFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + RoleDAO dao = DAOFactory.CreateRoleDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateRoleDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/RoleSystemActionRightCollection.cs b/DAL/CollectionClasses/RoleSystemActionRightCollection.cs new file mode 100644 index 0000000..d15cc94 --- /dev/null +++ b/DAL/CollectionClasses/RoleSystemActionRightCollection.cs @@ -0,0 +1,277 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of RoleSystemActionRightEntity objects. + [Serializable] + public partial class RoleSystemActionRightCollection : EntityCollectionBase + { + /// CTor + public RoleSystemActionRightCollection():base(new RoleSystemActionRightEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public RoleSystemActionRightCollection(IList initialContents):base(new RoleSystemActionRightEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public RoleSystemActionRightCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected RoleSystemActionRightCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this RoleSystemActionRightCollection object all RoleSystemActionRightEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity actionRightInstance, IEntity roleInstance) + { + return GetMultiManyToOne(actionRightInstance, roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this RoleSystemActionRightCollection object all RoleSystemActionRightEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity actionRightInstance, IEntity roleInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(actionRightInstance, roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this RoleSystemActionRightCollection object all RoleSystemActionRightEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity actionRightInstance, IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(actionRightInstance, roleInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this RoleSystemActionRightCollection object all RoleSystemActionRightEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity actionRightInstance, IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (actionRightInstance!=null); + validParameters |= (roleInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleSystemActionRightDAO dao = DAOFactory.CreateRoleSystemActionRightDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, actionRightInstance, roleInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all RoleSystemActionRight entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity actionRightInstance, IEntity roleInstance) + { + RoleSystemActionRightDAO dao = DAOFactory.CreateRoleSystemActionRightDAO(); + return dao.DeleteMulti(base.Transaction, actionRightInstance, roleInstance); + } + + /// Updates in the persistent storage all RoleSystemActionRight entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// RoleSystemActionRightEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(RoleSystemActionRightEntity entityWithNewValues, IEntity actionRightInstance, IEntity roleInstance) + { + RoleSystemActionRightDAO dao = DAOFactory.CreateRoleSystemActionRightDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, actionRightInstance, roleInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + RoleSystemActionRightDAO dao = DAOFactory.CreateRoleSystemActionRightDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(RoleSystemActionRightFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(RoleSystemActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(RoleSystemActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(RoleSystemActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(RoleSystemActionRightFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + RoleSystemActionRightDAO dao = DAOFactory.CreateRoleSystemActionRightDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateRoleSystemActionRightDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/RoleUserCollection.cs b/DAL/CollectionClasses/RoleUserCollection.cs new file mode 100644 index 0000000..a736347 --- /dev/null +++ b/DAL/CollectionClasses/RoleUserCollection.cs @@ -0,0 +1,277 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of RoleUserEntity objects. + [Serializable] + public partial class RoleUserCollection : EntityCollectionBase + { + /// CTor + public RoleUserCollection():base(new RoleUserEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public RoleUserCollection(IList initialContents):base(new RoleUserEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public RoleUserCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected RoleUserCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this RoleUserCollection object all RoleUserEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to return + /// UserEntity instance to use as a filter for the RoleUserEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity roleInstance, IEntity userInstance) + { + return GetMultiManyToOne(roleInstance, userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this RoleUserCollection object all RoleUserEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to return + /// UserEntity instance to use as a filter for the RoleUserEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity roleInstance, IEntity userInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(roleInstance, userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this RoleUserCollection object all RoleUserEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to return + /// UserEntity instance to use as a filter for the RoleUserEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity roleInstance, IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(roleInstance, userInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this RoleUserCollection object all RoleUserEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to return + /// UserEntity instance to use as a filter for the RoleUserEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity roleInstance, IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (roleInstance!=null); + validParameters |= (userInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + RoleUserDAO dao = DAOFactory.CreateRoleUserDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, roleInstance, userInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all RoleUser entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to return + /// UserEntity instance to use as a filter for the RoleUserEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity roleInstance, IEntity userInstance) + { + RoleUserDAO dao = DAOFactory.CreateRoleUserDAO(); + return dao.DeleteMulti(base.Transaction, roleInstance, userInstance); + } + + /// Updates in the persistent storage all RoleUser entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// RoleUserEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to return + /// UserEntity instance to use as a filter for the RoleUserEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(RoleUserEntity entityWithNewValues, IEntity roleInstance, IEntity userInstance) + { + RoleUserDAO dao = DAOFactory.CreateRoleUserDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, roleInstance, userInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + RoleUserDAO dao = DAOFactory.CreateRoleUserDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(RoleUserFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(RoleUserFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(RoleUserFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(RoleUserFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(RoleUserFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + RoleUserDAO dao = DAOFactory.CreateRoleUserDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateRoleUserDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/SectionCollection.cs b/DAL/CollectionClasses/SectionCollection.cs new file mode 100644 index 0000000..da1faf2 --- /dev/null +++ b/DAL/CollectionClasses/SectionCollection.cs @@ -0,0 +1,194 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of SectionEntity objects. + [Serializable] + public partial class SectionCollection : EntityCollectionBase + { + /// CTor + public SectionCollection():base(new SectionEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public SectionCollection(IList initialContents):base(new SectionEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public SectionCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected SectionCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + SectionDAO dao = DAOFactory.CreateSectionDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(SectionFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(SectionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(SectionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(SectionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(SectionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + SectionDAO dao = DAOFactory.CreateSectionDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateSectionDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/SupportQueueCollection.cs b/DAL/CollectionClasses/SupportQueueCollection.cs new file mode 100644 index 0000000..3971779 --- /dev/null +++ b/DAL/CollectionClasses/SupportQueueCollection.cs @@ -0,0 +1,194 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of SupportQueueEntity objects. + [Serializable] + public partial class SupportQueueCollection : EntityCollectionBase + { + /// CTor + public SupportQueueCollection():base(new SupportQueueEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public SupportQueueCollection(IList initialContents):base(new SupportQueueEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public SupportQueueCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected SupportQueueCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + SupportQueueDAO dao = DAOFactory.CreateSupportQueueDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(SupportQueueFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(SupportQueueFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(SupportQueueFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(SupportQueueFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(SupportQueueFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + SupportQueueDAO dao = DAOFactory.CreateSupportQueueDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateSupportQueueDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/SupportQueueThreadCollection.cs b/DAL/CollectionClasses/SupportQueueThreadCollection.cs new file mode 100644 index 0000000..9b33d7c --- /dev/null +++ b/DAL/CollectionClasses/SupportQueueThreadCollection.cs @@ -0,0 +1,284 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of SupportQueueThreadEntity objects. + [Serializable] + public partial class SupportQueueThreadCollection : EntityCollectionBase + { + /// CTor + public SupportQueueThreadCollection():base(new SupportQueueThreadEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public SupportQueueThreadCollection(IList initialContents):base(new SupportQueueThreadEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public SupportQueueThreadCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected SupportQueueThreadCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this SupportQueueThreadCollection object all SupportQueueThreadEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance) + { + return GetMultiManyToOne(supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this SupportQueueThreadCollection object all SupportQueueThreadEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this SupportQueueThreadCollection object all SupportQueueThreadEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this SupportQueueThreadCollection object all SupportQueueThreadEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (supportQueueInstance!=null); + validParameters |= (claimedByUserInstance!=null); + validParameters |= (placedInQueueByUserInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + SupportQueueThreadDAO dao = DAOFactory.CreateSupportQueueThreadDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all SupportQueueThread entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance) + { + SupportQueueThreadDAO dao = DAOFactory.CreateSupportQueueThreadDAO(); + return dao.DeleteMulti(base.Transaction, supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance); + } + + /// Updates in the persistent storage all SupportQueueThread entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// SupportQueueThreadEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(SupportQueueThreadEntity entityWithNewValues, IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance) + { + SupportQueueThreadDAO dao = DAOFactory.CreateSupportQueueThreadDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + SupportQueueThreadDAO dao = DAOFactory.CreateSupportQueueThreadDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(SupportQueueThreadFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(SupportQueueThreadFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(SupportQueueThreadFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(SupportQueueThreadFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(SupportQueueThreadFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + SupportQueueThreadDAO dao = DAOFactory.CreateSupportQueueThreadDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateSupportQueueThreadDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/SystemDataCollection.cs b/DAL/CollectionClasses/SystemDataCollection.cs new file mode 100644 index 0000000..2cc172c --- /dev/null +++ b/DAL/CollectionClasses/SystemDataCollection.cs @@ -0,0 +1,277 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of SystemDataEntity objects. + [Serializable] + public partial class SystemDataCollection : EntityCollectionBase + { + /// CTor + public SystemDataCollection():base(new SystemDataEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public SystemDataCollection(IList initialContents):base(new SystemDataEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public SystemDataCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected SystemDataCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this SystemDataCollection object all SystemDataEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance) + { + return GetMultiManyToOne(roleForAnonymousInstance, roleForNewUserInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this SystemDataCollection object all SystemDataEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(roleForAnonymousInstance, roleForNewUserInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this SystemDataCollection object all SystemDataEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(roleForAnonymousInstance, roleForNewUserInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this SystemDataCollection object all SystemDataEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (roleForAnonymousInstance!=null); + validParameters |= (roleForNewUserInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + SystemDataDAO dao = DAOFactory.CreateSystemDataDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, roleForAnonymousInstance, roleForNewUserInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all SystemData entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance) + { + SystemDataDAO dao = DAOFactory.CreateSystemDataDAO(); + return dao.DeleteMulti(base.Transaction, roleForAnonymousInstance, roleForNewUserInstance); + } + + /// Updates in the persistent storage all SystemData entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// SystemDataEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(SystemDataEntity entityWithNewValues, IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance) + { + SystemDataDAO dao = DAOFactory.CreateSystemDataDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, roleForAnonymousInstance, roleForNewUserInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + SystemDataDAO dao = DAOFactory.CreateSystemDataDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(SystemDataFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(SystemDataFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(SystemDataFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(SystemDataFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(SystemDataFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + SystemDataDAO dao = DAOFactory.CreateSystemDataDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateSystemDataDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/ThreadCollection.cs b/DAL/CollectionClasses/ThreadCollection.cs new file mode 100644 index 0000000..aa60434 --- /dev/null +++ b/DAL/CollectionClasses/ThreadCollection.cs @@ -0,0 +1,471 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of ThreadEntity objects. + [Serializable] + public partial class ThreadCollection : EntityCollectionBase + { + /// CTor + public ThreadCollection():base(new ThreadEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public ThreadCollection(IList initialContents):base(new ThreadEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public ThreadCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected ThreadCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ForumEntity instance to use as a filter for the ThreadEntity objects to return + /// UserEntity instance to use as a filter for the ThreadEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity forumInstance, IEntity userWhoStartedThreadInstance) + { + return GetMultiManyToOne(forumInstance, userWhoStartedThreadInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ForumEntity instance to use as a filter for the ThreadEntity objects to return + /// UserEntity instance to use as a filter for the ThreadEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity forumInstance, IEntity userWhoStartedThreadInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(forumInstance, userWhoStartedThreadInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ForumEntity instance to use as a filter for the ThreadEntity objects to return + /// UserEntity instance to use as a filter for the ThreadEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity forumInstance, IEntity userWhoStartedThreadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(forumInstance, userWhoStartedThreadInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ForumEntity instance to use as a filter for the ThreadEntity objects to return + /// UserEntity instance to use as a filter for the ThreadEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity forumInstance, IEntity userWhoStartedThreadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (forumInstance!=null); + validParameters |= (userWhoStartedThreadInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, forumInstance, userWhoStartedThreadInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all Thread entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// ForumEntity instance to use as a filter for the ThreadEntity objects to return + /// UserEntity instance to use as a filter for the ThreadEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity forumInstance, IEntity userWhoStartedThreadInstance) + { + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.DeleteMulti(base.Transaction, forumInstance, userWhoStartedThreadInstance); + } + + /// Updates in the persistent storage all Thread entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// ThreadEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// ForumEntity instance to use as a filter for the ThreadEntity objects to return + /// UserEntity instance to use as a filter for the ThreadEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(ThreadEntity entityWithNewValues, IEntity forumInstance, IEntity userWhoStartedThreadInstance) + { + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, forumInstance, userWhoStartedThreadInstance); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoSubscribedThread(IEntity userInstance) + { + return GetMultiManyToManyUsingUsersWhoSubscribedThread(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoSubscribedThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingUsersWhoSubscribedThread(userInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingUsersWhoSubscribedThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetMultiUsingUsersWhoSubscribedThread(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, pageNumber, pageSize); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoSubscribedThread(IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingUsersWhoSubscribedThread(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoSubscribedThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetMultiUsingUsersWhoSubscribedThread(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, prefetchPathToUse); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoPostedInThread(IEntity userInstance) + { + return GetMultiManyToManyUsingUsersWhoPostedInThread(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoPostedInThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingUsersWhoPostedInThread(userInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingUsersWhoPostedInThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetMultiUsingUsersWhoPostedInThread(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, pageNumber, pageSize); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoPostedInThread(IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingUsersWhoPostedInThread(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoPostedInThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetMultiUsingUsersWhoPostedInThread(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, prefetchPathToUse); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoBookmarkedThread(IEntity userInstance) + { + return GetMultiManyToManyUsingUsersWhoBookmarkedThread(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoBookmarkedThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingUsersWhoBookmarkedThread(userInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingUsersWhoBookmarkedThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetMultiUsingUsersWhoBookmarkedThread(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, pageNumber, pageSize); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a Relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoBookmarkedThread(IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingUsersWhoBookmarkedThread(userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this ThreadCollection object all ThreadEntity objects which are related via a relation of type 'm:n' with the passed in UserEntity. + /// All current elements in the collection are removed from the collection. + /// UserEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingUsersWhoBookmarkedThread(IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetMultiUsingUsersWhoBookmarkedThread(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, userInstance, prefetchPathToUse); + } + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ThreadFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ThreadFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ThreadFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ThreadFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(ThreadFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + ThreadDAO dao = DAOFactory.CreateThreadDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateThreadDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/ThreadSubscriptionCollection.cs b/DAL/CollectionClasses/ThreadSubscriptionCollection.cs new file mode 100644 index 0000000..1aacc0d --- /dev/null +++ b/DAL/CollectionClasses/ThreadSubscriptionCollection.cs @@ -0,0 +1,277 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of ThreadSubscriptionEntity objects. + [Serializable] + public partial class ThreadSubscriptionCollection : EntityCollectionBase + { + /// CTor + public ThreadSubscriptionCollection():base(new ThreadSubscriptionEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public ThreadSubscriptionCollection(IList initialContents):base(new ThreadSubscriptionEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public ThreadSubscriptionCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected ThreadSubscriptionCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this ThreadSubscriptionCollection object all ThreadSubscriptionEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity userInstance) + { + return GetMultiManyToOne(threadInstance, userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this ThreadSubscriptionCollection object all ThreadSubscriptionEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity userInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(threadInstance, userInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this ThreadSubscriptionCollection object all ThreadSubscriptionEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity threadInstance, IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(threadInstance, userInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this ThreadSubscriptionCollection object all ThreadSubscriptionEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity threadInstance, IEntity userInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (threadInstance!=null); + validParameters |= (userInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + ThreadSubscriptionDAO dao = DAOFactory.CreateThreadSubscriptionDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, threadInstance, userInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all ThreadSubscription entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity threadInstance, IEntity userInstance) + { + ThreadSubscriptionDAO dao = DAOFactory.CreateThreadSubscriptionDAO(); + return dao.DeleteMulti(base.Transaction, threadInstance, userInstance); + } + + /// Updates in the persistent storage all ThreadSubscription entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// ThreadSubscriptionEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(ThreadSubscriptionEntity entityWithNewValues, IEntity threadInstance, IEntity userInstance) + { + ThreadSubscriptionDAO dao = DAOFactory.CreateThreadSubscriptionDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, threadInstance, userInstance); + } + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + ThreadSubscriptionDAO dao = DAOFactory.CreateThreadSubscriptionDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ThreadSubscriptionFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(ThreadSubscriptionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ThreadSubscriptionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(ThreadSubscriptionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(ThreadSubscriptionFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + ThreadSubscriptionDAO dao = DAOFactory.CreateThreadSubscriptionDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateThreadSubscriptionDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/UserCollection.cs b/DAL/CollectionClasses/UserCollection.cs new file mode 100644 index 0000000..83c1f6a --- /dev/null +++ b/DAL/CollectionClasses/UserCollection.cs @@ -0,0 +1,594 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of UserEntity objects. + [Serializable] + public partial class UserCollection : EntityCollectionBase + { + /// CTor + public UserCollection():base(new UserEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public UserCollection(IList initialContents):base(new UserEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public UserCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected UserCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + /// Retrieves in this UserCollection object all UserEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// UserTitleEntity instance to use as a filter for the UserEntity objects to return + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity userTitleInstance) + { + return GetMultiManyToOne(userTitleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, null, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// UserTitleEntity instance to use as a filter for the UserEntity objects to return + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity userTitleInstance, IPredicateExpression filter) + { + return GetMultiManyToOne(userTitleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, filter, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// UserTitleEntity instance to use as a filter for the UserEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// true if succeeded, false otherwise + public bool GetMultiManyToOne(IEntity userTitleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter) + { + return GetMultiManyToOne(userTitleInstance, maxNumberOfItemsToReturn, sortClauses, filter, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which have data in common with the specified related Entities. + /// If one is omitted, that entity is not used as a filter. All current elements in the collection are removed from the collection. + /// UserTitleEntity instance to use as a filter for the UserEntity objects to return + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public virtual bool GetMultiManyToOne(IEntity userTitleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicateExpression filter, int pageNumber, int pageSize) + { + bool validParameters = false; + validParameters |= (userTitleInstance!=null); + if(!validParameters) + { + return GetMulti(filter, maxNumberOfItemsToReturn, sortClauses, null, pageNumber, pageSize); + } + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMulti(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, filter, userTitleInstance, pageNumber, pageSize); + } + + /// Deletes from the persistent storage all User entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Runs directly on the persistent storage. It will not delete entity objects from the current collection. + /// UserTitleEntity instance to use as a filter for the UserEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMultiManyToOne(IEntity userTitleInstance) + { + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.DeleteMulti(base.Transaction, userTitleInstance); + } + + /// Updates in the persistent storage all User entities which have data in common with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// Which fields are updated in those matching entities depends on which fields are changed in the passed in entity entityWithNewValues. The new values of these fields are read from entityWithNewValues. + /// UserEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// UserTitleEntity instance to use as a filter for the UserEntity objects to return + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMultiManyToOne(UserEntity entityWithNewValues, IEntity userTitleInstance) + { + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.UpdateMulti(entityWithNewValues, base.Transaction, userTitleInstance); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in ForumEntity. + /// All current elements in the collection are removed from the collection. + /// ForumEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingStartedThreadsInForums(IEntity forumInstance) + { + return GetMultiManyToManyUsingStartedThreadsInForums(forumInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ForumEntity. + /// All current elements in the collection are removed from the collection. + /// ForumEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingStartedThreadsInForums(IEntity forumInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingStartedThreadsInForums(forumInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ForumEntity. + /// All current elements in the collection are removed from the collection. + /// ForumEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingStartedThreadsInForums(IEntity forumInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingStartedThreadsInForums(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, forumInstance, pageNumber, pageSize); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in ForumEntity. + /// All current elements in the collection are removed from the collection. + /// ForumEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingStartedThreadsInForums(IEntity forumInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingStartedThreadsInForums(forumInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ForumEntity. + /// All current elements in the collection are removed from the collection. + /// ForumEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingStartedThreadsInForums(IEntity forumInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingStartedThreadsInForums(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, forumInstance, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingRoles(IEntity roleInstance) + { + return GetMultiManyToManyUsingRoles(roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingRoles(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingRoles(roleInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingRoles(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingRoles(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, roleInstance, pageNumber, pageSize); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingRoles(IEntity roleInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingRoles(roleInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// All current elements in the collection are removed from the collection. + /// RoleEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingRoles(IEntity roleInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingRoles(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, roleInstance, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingThreadCollectionViaThreadSubscription(IEntity threadInstance) + { + return GetMultiManyToManyUsingThreadCollectionViaThreadSubscription(threadInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingThreadCollectionViaThreadSubscription(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingThreadCollectionViaThreadSubscription(threadInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingThreadCollectionViaThreadSubscription(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingThreadCollectionViaThreadSubscription(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, threadInstance, pageNumber, pageSize); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingThreadCollectionViaThreadSubscription(IEntity threadInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingThreadCollectionViaThreadSubscription(threadInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingThreadCollectionViaThreadSubscription(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingThreadCollectionViaThreadSubscription(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, threadInstance, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingPostedMessagesInThreads(IEntity threadInstance) + { + return GetMultiManyToManyUsingPostedMessagesInThreads(threadInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingPostedMessagesInThreads(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingPostedMessagesInThreads(threadInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingPostedMessagesInThreads(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingPostedMessagesInThreads(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, threadInstance, pageNumber, pageSize); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingPostedMessagesInThreads(IEntity threadInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingPostedMessagesInThreads(threadInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingPostedMessagesInThreads(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingPostedMessagesInThreads(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, threadInstance, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingThreadsInBookmarks(IEntity threadInstance) + { + return GetMultiManyToManyUsingThreadsInBookmarks(threadInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingThreadsInBookmarks(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiManyToManyUsingThreadsInBookmarks(threadInstance, maxNumberOfItemsToReturn, sortClauses, 0, 0); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if the retrieval succeeded, false otherwise + public virtual bool GetMultiManyToManyUsingThreadsInBookmarks(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, int pageNumber, int pageSize) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingThreadsInBookmarks(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, threadInstance, pageNumber, pageSize); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a Relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingThreadsInBookmarks(IEntity threadInstance, IPrefetchPath prefetchPathToUse) + { + return GetMultiManyToManyUsingThreadsInBookmarks(threadInstance, base.MaxNumberOfItemsToReturn, base.SortClauses, prefetchPathToUse); + } + + /// Retrieves in this UserCollection object all UserEntity objects which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// All current elements in the collection are removed from the collection. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if the retrieval succeeded, false otherwise + public bool GetMultiManyToManyUsingThreadsInBookmarks(IEntity threadInstance, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPathToUse) + { + if(!base.SuppressClearInGetMulti) + { + this.Clear(); + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiUsingThreadsInBookmarks(base.Transaction, this, maxNumberOfItemsToReturn, sortClauses, base.EntityFactoryToUse, threadInstance, prefetchPathToUse); + } + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(UserFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(UserFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(UserFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(UserFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(UserFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + UserDAO dao = DAOFactory.CreateUserDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateUserDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/CollectionClasses/UserTitleCollection.cs b/DAL/CollectionClasses/UserTitleCollection.cs new file mode 100644 index 0000000..8c7ab4f --- /dev/null +++ b/DAL/CollectionClasses/UserTitleCollection.cs @@ -0,0 +1,194 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.CollectionClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Collection class for storing and retrieving collections of UserTitleEntity objects. + [Serializable] + public partial class UserTitleCollection : EntityCollectionBase + { + /// CTor + public UserTitleCollection():base(new UserTitleEntityFactory()) + { + } + + /// CTor + /// The initial contents of this collection. + public UserTitleCollection(IList initialContents):base(new UserTitleEntityFactory()) + { + AddRange(initialContents); + } + + /// CTor + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + public UserTitleCollection(IEntityFactory entityFactoryToUse):base(entityFactoryToUse) + { + } + + /// Private CTor for deserialization + /// + /// + protected UserTitleCollection(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + + + + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, null, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations) + { + return GetMultiAsDataTable(selectFilter, maxNumberOfItemsToReturn, sortClauses, relations, 0, 0); + } + + /// Retrieves Entity rows in a datatable which match the specified filter. It will always create a new connection to the database. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The maximum number of items to return with this retrieval query. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// DataTable with the rows requested. + public static DataTable GetMultiAsDataTable(IPredicate selectFilter, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, int pageNumber, int pageSize) + { + UserTitleDAO dao = DAOFactory.CreateUserTitleDAO(); + return dao.GetMultiAsDataTable(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// Gets a scalar value, calculated with the aggregate. the field index specified is the field the aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(UserTitleFieldIndex fieldIndex, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, null, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// the scalar value requested + public object GetScalar(UserTitleFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, null, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are + /// applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(UserTitleFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, null); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public object GetScalar(UserTitleFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IGroupByCollection groupByClause) + { + return GetScalar(fieldIndex, expressionToExecute, aggregateToApply, filter, null, groupByClause); + } + + /// Gets a scalar value, calculated with the aggregate and expression specified. the field index specified is the field the expression and aggregate are applied on. + /// Field index of field to which to apply the aggregate function and expression + /// The expression to execute. Can be null + /// Aggregate function to apply. + /// The filter to apply to retrieve the scalar + /// The relations to walk + /// The groupby clause to apply to retrieve the scalar + /// the scalar value requested + public virtual object GetScalar(UserTitleFieldIndex fieldIndex, IExpression expressionToExecute, AggregateFunction aggregateToApply, IPredicate filter, IRelationCollection relations, IGroupByCollection groupByClause) + { + EntityFields fields = new EntityFields(1); + fields[0] = EntityFieldFactory.Create(fieldIndex); + if((fields[0].ExpressionToApply == null) || (expressionToExecute != null)) + { + fields[0].ExpressionToApply = expressionToExecute; + } + if((fields[0].AggregateFunctionToApply == AggregateFunction.None) || (aggregateToApply != AggregateFunction.None)) + { + fields[0].AggregateFunctionToApply = aggregateToApply; + } + UserTitleDAO dao = DAOFactory.CreateUserTitleDAO(); + return dao.GetScalar(fields, base.Transaction, filter, relations, groupByClause); + } + + /// Creats a new DAO instance so code which is in the base class can still use the proper DAO object. + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateUserTitleDAO(); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + + #region Custom EntityCollection code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCollectionCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/ConstantsEnums.cs b/DAL/ConstantsEnums.cs new file mode 100644 index 0000000..029d28a --- /dev/null +++ b/DAL/ConstantsEnums.cs @@ -0,0 +1,680 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; + +namespace SD.HnD.DAL +{ + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: ActionRight. + /// + public enum ActionRightFieldIndex:int + { + ///ActionRightID. + ActionRightID, + ///ActionRightDescription. + ActionRightDescription, + ///AppliesToForum. + AppliesToForum, + ///AppliesToSystem. + AppliesToSystem, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: Attachment. + /// + public enum AttachmentFieldIndex:int + { + ///AttachmentID. + AttachmentID, + ///MessageID. + MessageID, + ///Filename. + Filename, + ///Approved. + Approved, + ///Filecontents. + Filecontents, + ///Filesize. + Filesize, + ///AddedOn. + AddedOn, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: AuditAction. + /// + public enum AuditActionFieldIndex:int + { + ///AuditActionID. + AuditActionID, + ///AuditActionDescription. + AuditActionDescription, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: AuditDataCore. + /// + public enum AuditDataCoreFieldIndex:int + { + ///AuditDataID. + AuditDataID, + ///AuditActionID. + AuditActionID, + ///UserID. + UserID, + ///AuditedOn. + AuditedOn, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: AuditDataMessageRelated. + /// + public enum AuditDataMessageRelatedFieldIndex:int + { + ///AuditDataID. Inherited from AuditDataCore + AuditDataID_AuditDataCore, + ///AuditActionID. + AuditActionID, + ///UserID. + UserID, + ///AuditedOn. + AuditedOn, + ///AuditDataID. + AuditDataID, + ///MessageID. + MessageID, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: AuditDataThreadRelated. + /// + public enum AuditDataThreadRelatedFieldIndex:int + { + ///AuditDataID. Inherited from AuditDataCore + AuditDataID_AuditDataCore, + ///AuditActionID. + AuditActionID, + ///UserID. + UserID, + ///AuditedOn. + AuditedOn, + ///AuditDataID. + AuditDataID, + ///ThreadID. + ThreadID, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: Bookmark. + /// + public enum BookmarkFieldIndex:int + { + ///ThreadID. + ThreadID, + ///UserID. + UserID, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: Forum. + /// + public enum ForumFieldIndex:int + { + ///ForumID. + ForumID, + ///SectionID. + SectionID, + ///ForumName. + ForumName, + ///ForumDescription. + ForumDescription, + ///ForumLastPostingDate. + ForumLastPostingDate, + ///HasRSSFeed. + HasRSSFeed, + ///DefaultSupportQueueID. + DefaultSupportQueueID, + ///DefaultThreadListInterval. + DefaultThreadListInterval, + ///OrderNo. + OrderNo, + ///MaxAttachmentSize. + MaxAttachmentSize, + ///MaxNoOfAttachmentsPerMessage. + MaxNoOfAttachmentsPerMessage, + ///NewThreadWelcomeText. + NewThreadWelcomeText, + ///NewThreadWelcomeTextAsHTML. + NewThreadWelcomeTextAsHTML, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: ForumRoleForumActionRight. + /// + public enum ForumRoleForumActionRightFieldIndex:int + { + ///ForumID. + ForumID, + ///RoleID. + RoleID, + ///ActionRightID. + ActionRightID, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: IPBan. + /// + public enum IPBanFieldIndex:int + { + ///IPBanID. + IPBanID, + ///IPSegment1. + IPSegment1, + ///IPSegment2. + IPSegment2, + ///IPSegment3. + IPSegment3, + ///IPSegment4. + IPSegment4, + ///Range. + Range, + ///IPBanSetByUserID. + IPBanSetByUserID, + ///IPBanSetOn. + IPBanSetOn, + ///Reason. + Reason, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: Message. + /// + public enum MessageFieldIndex:int + { + ///MessageID. + MessageID, + ///PostingDate. + PostingDate, + ///PostedByUserID. + PostedByUserID, + ///ThreadID. + ThreadID, + ///PostedFromIP. + PostedFromIP, + ///ChangeTrackerStamp. + ChangeTrackerStamp, + ///MessageText. + MessageText, + ///MessageTextAsHTML. + MessageTextAsHTML, + ///MessageTextAsXml. + MessageTextAsXml, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: Role. + /// + public enum RoleFieldIndex:int + { + ///RoleID. + RoleID, + ///RoleDescription. + RoleDescription, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: RoleAuditAction. + /// + public enum RoleAuditActionFieldIndex:int + { + ///AuditActionID. + AuditActionID, + ///RoleID. + RoleID, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: RoleSystemActionRight. + /// + public enum RoleSystemActionRightFieldIndex:int + { + ///RoleID. + RoleID, + ///ActionRightID. + ActionRightID, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: RoleUser. + /// + public enum RoleUserFieldIndex:int + { + ///RoleID. + RoleID, + ///UserID. + UserID, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: Section. + /// + public enum SectionFieldIndex:int + { + ///SectionID. + SectionID, + ///SectionName. + SectionName, + ///SectionDescription. + SectionDescription, + ///OrderNo. + OrderNo, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: SupportQueue. + /// + public enum SupportQueueFieldIndex:int + { + ///QueueID. + QueueID, + ///QueueName. + QueueName, + ///QueueDescription. + QueueDescription, + ///OrderNo. + OrderNo, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: SupportQueueThread. + /// + public enum SupportQueueThreadFieldIndex:int + { + ///QueueID. + QueueID, + ///ThreadID. + ThreadID, + ///PlacedInQueueByUserID. + PlacedInQueueByUserID, + ///PlacedInQueueOn. + PlacedInQueueOn, + ///ClaimedByUserID. + ClaimedByUserID, + ///ClaimedOn. + ClaimedOn, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: SystemData. + /// + public enum SystemDataFieldIndex:int + { + ///ID. + ID, + ///DefaultRoleNewUser. + DefaultRoleNewUser, + ///AnonymousRole. + AnonymousRole, + ///DefaultUserTitleNewUser. + DefaultUserTitleNewUser, + ///HoursThresholdForActiveThreads. + HoursThresholdForActiveThreads, + ///PageSizeSearchResults. + PageSizeSearchResults, + ///MinNumberOfThreadsToFetch. + MinNumberOfThreadsToFetch, + ///MinNumberOfNonStickyVisibleThreads. + MinNumberOfNonStickyVisibleThreads, + ///SendReplyNotifications. + SendReplyNotifications, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: Thread. + /// + public enum ThreadFieldIndex:int + { + ///ThreadID. + ThreadID, + ///ForumID. + ForumID, + ///Subject. + Subject, + ///StartedByUserID. + StartedByUserID, + ///ThreadLastPostingDate. + ThreadLastPostingDate, + ///IsSticky. + IsSticky, + ///IsClosed. + IsClosed, + ///MarkedAsDone. + MarkedAsDone, + ///NumberOfViews. + NumberOfViews, + ///Memo. + Memo, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: ThreadSubscription. + /// + public enum ThreadSubscriptionFieldIndex:int + { + ///UserID. + UserID, + ///ThreadID. + ThreadID, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: User. + /// + public enum UserFieldIndex:int + { + ///UserID. + UserID, + ///NickName. + NickName, + ///Password. + Password, + ///IsBanned. + IsBanned, + ///IPNumber. + IPNumber, + ///Signature. + Signature, + ///IconURL. + IconURL, + ///EmailAddress. + EmailAddress, + ///UserTitleID. + UserTitleID, + ///DateOfBirth. + DateOfBirth, + ///Occupation. + Occupation, + ///Location. + Location, + ///Website. + Website, + ///SignatureAsHTML. + SignatureAsHTML, + ///JoinDate. + JoinDate, + ///AmountOfPostings. + AmountOfPostings, + ///EmailAddressIsPublic. + EmailAddressIsPublic, + ///LastVisitedDate. + LastVisitedDate, + ///AutoSubscribeToThread. + AutoSubscribeToThread, + ///DefaultNumberOfMessagesPerPage. + DefaultNumberOfMessagesPerPage, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access EntityFields in the IEntityFields collection for the entity: UserTitle. + /// + public enum UserTitleFieldIndex:int + { + ///UserTitleID. + UserTitleID, + ///UserTitleDescription. + UserTitleDescription, + /// + AmountOfFields + } + + + + /// + /// Index enum to fast-access TypedList Fields in the Columns collection of the Typed List: ForumMessages + /// + public enum ForumMessagesTypedListFieldIndex:int + { + ///MessageID + MessageID, + ///PostingDate + PostingDate, + ///MessageTextAsHTML + MessageTextAsHTML, + ///ThreadID + ThreadID, + ///Subject + Subject, + ///EmailAddress + EmailAddress, + ///EmailAddressIsPublic + EmailAddressIsPublic, + ///NickName + NickName, + ///MessageText + MessageText, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access TypedList Fields in the Columns collection of the Typed List: ForumsWithSectionName + /// + public enum ForumsWithSectionNameTypedListFieldIndex:int + { + ///ForumID + ForumID, + ///ForumName + ForumName, + ///SectionName + SectionName, + ///ForumDescription + ForumDescription, + ///SectionID + SectionID, + ///ForumOrderNo + ForumOrderNo, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access TypedList Fields in the Columns collection of the Typed List: MessagesInThread + /// + public enum MessagesInThreadTypedListFieldIndex:int + { + ///MessageID + MessageID, + ///PostingDate + PostingDate, + ///MessageTextAsHTML + MessageTextAsHTML, + ///ThreadID + ThreadID, + ///PostedFromIP + PostedFromIP, + ///UserID + UserID, + ///NickName + NickName, + ///SignatureAsHTML + SignatureAsHTML, + ///IconURL + IconURL, + ///Location + Location, + ///JoinDate + JoinDate, + ///AmountOfPostings + AmountOfPostings, + ///UserTitleDescription + UserTitleDescription, + /// + AmountOfFields + } + + + /// + /// Index enum to fast-access TypedList Fields in the Columns collection of the Typed List: SearchResult + /// + public enum SearchResultTypedListFieldIndex:int + { + ///ThreadID + ThreadID, + ///Subject + Subject, + ///ForumName + ForumName, + ///SectionName + SectionName, + ///ThreadLastPostingDate + ThreadLastPostingDate, + /// + AmountOfFields + } + + + + /// + /// Enum definition for all the entity types defined in this namespace. Used by the entityfields factory. + /// + public enum EntityType:int + { + ///ActionRight + ActionRightEntity, + ///Attachment + AttachmentEntity, + ///AuditAction + AuditActionEntity, + ///AuditDataCore + AuditDataCoreEntity, + ///AuditDataMessageRelated + AuditDataMessageRelatedEntity, + ///AuditDataThreadRelated + AuditDataThreadRelatedEntity, + ///Bookmark + BookmarkEntity, + ///Forum + ForumEntity, + ///ForumRoleForumActionRight + ForumRoleForumActionRightEntity, + ///IPBan + IPBanEntity, + ///Message + MessageEntity, + ///Role + RoleEntity, + ///RoleAuditAction + RoleAuditActionEntity, + ///RoleSystemActionRight + RoleSystemActionRightEntity, + ///RoleUser + RoleUserEntity, + ///Section + SectionEntity, + ///SupportQueue + SupportQueueEntity, + ///SupportQueueThread + SupportQueueThreadEntity, + ///SystemData + SystemDataEntity, + ///Thread + ThreadEntity, + ///ThreadSubscription + ThreadSubscriptionEntity, + ///User + UserEntity, + ///UserTitle + UserTitleEntity + } + + + + + #region Custom ConstantsEnums Code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomUserConstants + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion +} + + diff --git a/DAL/DaoClasses/ActionRightDAO.cs b/DAL/DaoClasses/ActionRightDAO.cs new file mode 100644 index 0000000..61034f2 --- /dev/null +++ b/DAL/DaoClasses/ActionRightDAO.cs @@ -0,0 +1,153 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the ActionRight Entity. It will perform database oriented actions for + /// a entity of type 'ActionRightEntity'. This DAO works on an EntityFields object. + /// + public partial class ActionRightDAO : DaoBase + { + /// CTor + public ActionRightDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "ActionRightEntity", new ActionRightEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal ActionRightDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves entities of the type 'ActionRightEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Retrieves in the calling ActionRightCollection object all ActionRightEntity objects + /// which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// RoleEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingSystemRightAssignedToRoles(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity roleInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ActionRightEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ActionRightEntity.Relations.RoleSystemActionRightEntityUsingActionRightID, "RoleSystemActionRight_"); + relations.Add(RoleSystemActionRightEntity.Relations.RoleEntityUsingRoleID, "RoleSystemActionRight_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(roleInstance.Fields[(int)RoleFieldIndex.RoleID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling ActionRightCollection object all ActionRightEntity objects + /// which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// RoleEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingSystemRightAssignedToRoles(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity roleInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ActionRightEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ActionRightEntity.Relations.RoleSystemActionRightEntityUsingActionRightID, "RoleSystemActionRight_"); + relations.Add(RoleSystemActionRightEntity.Relations.RoleEntityUsingRoleID, "RoleSystemActionRight_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(roleInstance.Fields[(int)RoleFieldIndex.RoleID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/AttachmentDAO.cs b/DAL/DaoClasses/AttachmentDAO.cs new file mode 100644 index 0000000..2e2ab79 --- /dev/null +++ b/DAL/DaoClasses/AttachmentDAO.cs @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the Attachment Entity. It will perform database oriented actions for + /// a entity of type 'AttachmentEntity'. This DAO works on an EntityFields object. + /// + public partial class AttachmentDAO : DaoBase + { + /// CTor + public AttachmentDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "AttachmentEntity", new AttachmentEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal AttachmentDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling AttachmentCollection object all AttachmentEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity belongsToMessageInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AttachmentEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(belongsToMessageInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'AttachmentEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'Attachment' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity belongsToMessageInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AttachmentEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(belongsToMessageInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// MessageEntity instance to use as a filter for the AttachmentEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity belongsToMessageInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AttachmentEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(belongsToMessageInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// MessageEntity instance to use as a filter for the AttachmentEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity belongsToMessageInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(belongsToMessageInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AttachmentFieldIndex.MessageID], ComparisonOperator.Equal, ((MessageEntity)belongsToMessageInstance).MessageID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/AuditActionDAO.cs b/DAL/DaoClasses/AuditActionDAO.cs new file mode 100644 index 0000000..9e6e8c3 --- /dev/null +++ b/DAL/DaoClasses/AuditActionDAO.cs @@ -0,0 +1,153 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the AuditAction Entity. It will perform database oriented actions for + /// a entity of type 'AuditActionEntity'. This DAO works on an EntityFields object. + /// + public partial class AuditActionDAO : DaoBase + { + /// CTor + public AuditActionDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "AuditActionEntity", new AuditActionEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal AuditActionDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves entities of the type 'AuditActionEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Retrieves in the calling AuditActionCollection object all AuditActionEntity objects + /// which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// RoleEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingRolesWithAuditAction(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity roleInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditActionEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(AuditActionEntity.Relations.RoleAuditActionEntityUsingAuditActionID, "RoleAuditAction_"); + relations.Add(RoleAuditActionEntity.Relations.RoleEntityUsingRoleID, "RoleAuditAction_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(roleInstance.Fields[(int)RoleFieldIndex.RoleID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling AuditActionCollection object all AuditActionEntity objects + /// which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// RoleEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingRolesWithAuditAction(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity roleInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditActionEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(AuditActionEntity.Relations.RoleAuditActionEntityUsingAuditActionID, "RoleAuditAction_"); + relations.Add(RoleAuditActionEntity.Relations.RoleEntityUsingRoleID, "RoleAuditAction_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(roleInstance.Fields[(int)RoleFieldIndex.RoleID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/AuditDataCoreDAO.cs b/DAL/DaoClasses/AuditDataCoreDAO.cs new file mode 100644 index 0000000..f2e8ab7 --- /dev/null +++ b/DAL/DaoClasses/AuditDataCoreDAO.cs @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the AuditDataCore Entity. It will perform database oriented actions for + /// a entity of type 'AuditDataCoreEntity'. This DAO works on an EntityFields object. + /// + public partial class AuditDataCoreDAO : DaoBase + { + /// CTor + public AuditDataCoreDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.TargetPerEntity, "AuditDataCoreEntity", new AuditDataCoreEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal AuditDataCoreDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling AuditDataCoreCollection object all AuditDataCoreEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity auditActionInstance, IEntity userAuditedInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataCoreEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(auditActionInstance, userAuditedInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'AuditDataCoreEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'AuditDataCore' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to delete + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity auditActionInstance, IEntity userAuditedInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataCoreEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(auditActionInstance, userAuditedInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects to update + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity auditActionInstance, IEntity userAuditedInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataCoreEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(auditActionInstance, userAuditedInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// AuditActionEntity instance to use as a filter for the AuditDataCoreEntity objects + /// UserEntity instance to use as a filter for the AuditDataCoreEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity auditActionInstance, IEntity userAuditedInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(auditActionInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AuditDataCoreFieldIndex.AuditActionID], ComparisonOperator.Equal, ((AuditActionEntity)auditActionInstance).AuditActionID)); + } + if(userAuditedInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AuditDataCoreFieldIndex.UserID], ComparisonOperator.Equal, ((UserEntity)userAuditedInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/AuditDataMessageRelatedDAO.cs b/DAL/DaoClasses/AuditDataMessageRelatedDAO.cs new file mode 100644 index 0000000..c5ac552 --- /dev/null +++ b/DAL/DaoClasses/AuditDataMessageRelatedDAO.cs @@ -0,0 +1,174 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the AuditDataMessageRelated Entity. It will perform database oriented actions for + /// a entity of type 'AuditDataMessageRelatedEntity'. This DAO works on an EntityFields object. + /// + public partial class AuditDataMessageRelatedDAO : AuditDataCoreDAO + { + /// CTor + public AuditDataMessageRelatedDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.TargetPerEntity, "AuditDataMessageRelatedEntity", new AuditDataMessageRelatedEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal AuditDataMessageRelatedDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling AuditDataMessageRelatedCollection object all AuditDataMessageRelatedEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(auditActionInstance, messageInstance, userAuditedInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'AuditDataMessageRelatedEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public override DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'AuditDataMessageRelated' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to delete + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to delete + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(auditActionInstance, messageInstance, userAuditedInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to update + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to update + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(auditActionInstance, messageInstance, userAuditedInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// AuditActionEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects + /// MessageEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects + /// UserEntity instance to use as a filter for the AuditDataMessageRelatedEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity auditActionInstance, IEntity messageInstance, IEntity userAuditedInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(auditActionInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AuditDataMessageRelatedFieldIndex.AuditActionID], ComparisonOperator.Equal, ((AuditActionEntity)auditActionInstance).AuditActionID)); + } + if(messageInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AuditDataMessageRelatedFieldIndex.MessageID], ComparisonOperator.Equal, ((MessageEntity)messageInstance).MessageID)); + } + if(userAuditedInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AuditDataMessageRelatedFieldIndex.UserID], ComparisonOperator.Equal, ((UserEntity)userAuditedInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/AuditDataThreadRelatedDAO.cs b/DAL/DaoClasses/AuditDataThreadRelatedDAO.cs new file mode 100644 index 0000000..9b0b4ad --- /dev/null +++ b/DAL/DaoClasses/AuditDataThreadRelatedDAO.cs @@ -0,0 +1,174 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the AuditDataThreadRelated Entity. It will perform database oriented actions for + /// a entity of type 'AuditDataThreadRelatedEntity'. This DAO works on an EntityFields object. + /// + public partial class AuditDataThreadRelatedDAO : AuditDataCoreDAO + { + /// CTor + public AuditDataThreadRelatedDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.TargetPerEntity, "AuditDataThreadRelatedEntity", new AuditDataThreadRelatedEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal AuditDataThreadRelatedDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling AuditDataThreadRelatedCollection object all AuditDataThreadRelatedEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(auditActionInstance, threadInstance, userAuditedInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'AuditDataThreadRelatedEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public override DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'AuditDataThreadRelated' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to delete + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to delete + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(auditActionInstance, threadInstance, userAuditedInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to update + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to update + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(auditActionInstance, threadInstance, userAuditedInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// AuditActionEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects + /// ThreadEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects + /// UserEntity instance to use as a filter for the AuditDataThreadRelatedEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity auditActionInstance, IEntity threadInstance, IEntity userAuditedInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(auditActionInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AuditDataThreadRelatedFieldIndex.AuditActionID], ComparisonOperator.Equal, ((AuditActionEntity)auditActionInstance).AuditActionID)); + } + if(threadInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AuditDataThreadRelatedFieldIndex.ThreadID], ComparisonOperator.Equal, ((ThreadEntity)threadInstance).ThreadID)); + } + if(userAuditedInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)AuditDataThreadRelatedFieldIndex.UserID], ComparisonOperator.Equal, ((UserEntity)userAuditedInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/BookmarkDAO.cs b/DAL/DaoClasses/BookmarkDAO.cs new file mode 100644 index 0000000..176a3d8 --- /dev/null +++ b/DAL/DaoClasses/BookmarkDAO.cs @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the Bookmark Entity. It will perform database oriented actions for + /// a entity of type 'BookmarkEntity'. This DAO works on an EntityFields object. + /// + public partial class BookmarkDAO : DaoBase + { + /// CTor + public BookmarkDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "BookmarkEntity", new BookmarkEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal BookmarkDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling BookmarkCollection object all BookmarkEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to return + /// UserEntity instance to use as a filter for the BookmarkEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity threadInstance, IEntity userInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.BookmarkEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(threadInstance, userInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'BookmarkEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'Bookmark' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to delete + /// UserEntity instance to use as a filter for the BookmarkEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity threadInstance, IEntity userInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.BookmarkEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(threadInstance, userInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects to update + /// UserEntity instance to use as a filter for the BookmarkEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity threadInstance, IEntity userInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.BookmarkEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(threadInstance, userInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// ThreadEntity instance to use as a filter for the BookmarkEntity objects + /// UserEntity instance to use as a filter for the BookmarkEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity threadInstance, IEntity userInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(threadInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)BookmarkFieldIndex.ThreadID], ComparisonOperator.Equal, ((ThreadEntity)threadInstance).ThreadID)); + } + if(userInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)BookmarkFieldIndex.UserID], ComparisonOperator.Equal, ((UserEntity)userInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/ForumDAO.cs b/DAL/DaoClasses/ForumDAO.cs new file mode 100644 index 0000000..b3a7809 --- /dev/null +++ b/DAL/DaoClasses/ForumDAO.cs @@ -0,0 +1,235 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the Forum Entity. It will perform database oriented actions for + /// a entity of type 'ForumEntity'. This DAO works on an EntityFields object. + /// + public partial class ForumDAO : DaoBase + { + /// CTor + public ForumDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "ForumEntity", new ForumEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal ForumDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling ForumCollection object all ForumEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// SectionEntity instance to use as a filter for the ForumEntity objects to return + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity sectionInstance, IEntity defaultSupportQueueInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(sectionInstance, defaultSupportQueueInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'ForumEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Retrieves in the calling ForumCollection object all ForumEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsersWhoStartedThreads(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ForumEntity.Relations.ThreadEntityUsingForumID, "Thread_"); + relations.Add(ThreadEntity.Relations.UserEntityUsingStartedByUserID, "Thread_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling ForumCollection object all ForumEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsersWhoStartedThreads(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ForumEntity.Relations.ThreadEntityUsingForumID, "Thread_"); + relations.Add(ThreadEntity.Relations.UserEntityUsingStartedByUserID, "Thread_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + + /// + /// Deletes from the persistent storage all 'Forum' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// SectionEntity instance to use as a filter for the ForumEntity objects to delete + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity sectionInstance, IEntity defaultSupportQueueInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(sectionInstance, defaultSupportQueueInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// SectionEntity instance to use as a filter for the ForumEntity objects to update + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity sectionInstance, IEntity defaultSupportQueueInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(sectionInstance, defaultSupportQueueInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// SectionEntity instance to use as a filter for the ForumEntity objects + /// SupportQueueEntity instance to use as a filter for the ForumEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity sectionInstance, IEntity defaultSupportQueueInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(sectionInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ForumFieldIndex.SectionID], ComparisonOperator.Equal, ((SectionEntity)sectionInstance).SectionID)); + } + if(defaultSupportQueueInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ForumFieldIndex.DefaultSupportQueueID], ComparisonOperator.Equal, ((SupportQueueEntity)defaultSupportQueueInstance).QueueID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/ForumRoleForumActionRightDAO.cs b/DAL/DaoClasses/ForumRoleForumActionRightDAO.cs new file mode 100644 index 0000000..0ad2d17 --- /dev/null +++ b/DAL/DaoClasses/ForumRoleForumActionRightDAO.cs @@ -0,0 +1,193 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the ForumRoleForumActionRight Entity. It will perform database oriented actions for + /// a entity of type 'ForumRoleForumActionRightEntity'. This DAO works on an EntityFields object. + /// + public partial class ForumRoleForumActionRightDAO : DaoBase + { + /// CTor + public ForumRoleForumActionRightDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "ForumRoleForumActionRightEntity", new ForumRoleForumActionRightEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal ForumRoleForumActionRightDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling ForumRoleForumActionRightCollection object all ForumRoleForumActionRightEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(actionRightInstance, forumInstance, roleInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'ForumRoleForumActionRightEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'ForumRoleForumActionRight' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to delete + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to delete + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(actionRightInstance, forumInstance, roleInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to update + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to update + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(actionRightInstance, forumInstance, roleInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// ActionRightEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects + /// ForumEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects + /// RoleEntity instance to use as a filter for the ForumRoleForumActionRightEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity actionRightInstance, IEntity forumInstance, IEntity roleInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(actionRightInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ForumRoleForumActionRightFieldIndex.ActionRightID], ComparisonOperator.Equal, ((ActionRightEntity)actionRightInstance).ActionRightID)); + } + if(forumInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ForumRoleForumActionRightFieldIndex.ForumID], ComparisonOperator.Equal, ((ForumEntity)forumInstance).ForumID)); + } + if(roleInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ForumRoleForumActionRightFieldIndex.RoleID], ComparisonOperator.Equal, ((RoleEntity)roleInstance).RoleID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/IPBanDAO.cs b/DAL/DaoClasses/IPBanDAO.cs new file mode 100644 index 0000000..d749e25 --- /dev/null +++ b/DAL/DaoClasses/IPBanDAO.cs @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the IPBan Entity. It will perform database oriented actions for + /// a entity of type 'IPBanEntity'. This DAO works on an EntityFields object. + /// + public partial class IPBanDAO : DaoBase + { + /// CTor + public IPBanDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "IPBanEntity", new IPBanEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal IPBanDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling IPBanCollection object all IPBanEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// UserEntity instance to use as a filter for the IPBanEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity setByUserInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.IPBanEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(setByUserInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'IPBanEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'IPBan' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// UserEntity instance to use as a filter for the IPBanEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity setByUserInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.IPBanEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(setByUserInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// UserEntity instance to use as a filter for the IPBanEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity setByUserInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.IPBanEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(setByUserInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// UserEntity instance to use as a filter for the IPBanEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity setByUserInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(setByUserInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)IPBanFieldIndex.IPBanSetByUserID], ComparisonOperator.Equal, ((UserEntity)setByUserInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/MessageDAO.cs b/DAL/DaoClasses/MessageDAO.cs new file mode 100644 index 0000000..12e22db --- /dev/null +++ b/DAL/DaoClasses/MessageDAO.cs @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the Message Entity. It will perform database oriented actions for + /// a entity of type 'MessageEntity'. This DAO works on an EntityFields object. + /// + public partial class MessageDAO : DaoBase + { + /// CTor + public MessageDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "MessageEntity", new MessageEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal MessageDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling MessageCollection object all MessageEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// ThreadEntity instance to use as a filter for the MessageEntity objects to return + /// UserEntity instance to use as a filter for the MessageEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity threadInstance, IEntity postedByUserInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.MessageEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(threadInstance, postedByUserInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'MessageEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'Message' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ThreadEntity instance to use as a filter for the MessageEntity objects to delete + /// UserEntity instance to use as a filter for the MessageEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity threadInstance, IEntity postedByUserInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.MessageEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(threadInstance, postedByUserInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ThreadEntity instance to use as a filter for the MessageEntity objects to update + /// UserEntity instance to use as a filter for the MessageEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity threadInstance, IEntity postedByUserInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.MessageEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(threadInstance, postedByUserInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// ThreadEntity instance to use as a filter for the MessageEntity objects + /// UserEntity instance to use as a filter for the MessageEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity threadInstance, IEntity postedByUserInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(threadInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)MessageFieldIndex.ThreadID], ComparisonOperator.Equal, ((ThreadEntity)threadInstance).ThreadID)); + } + if(postedByUserInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)MessageFieldIndex.PostedByUserID], ComparisonOperator.Equal, ((UserEntity)postedByUserInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/RoleAuditActionDAO.cs b/DAL/DaoClasses/RoleAuditActionDAO.cs new file mode 100644 index 0000000..f3a8ed8 --- /dev/null +++ b/DAL/DaoClasses/RoleAuditActionDAO.cs @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the RoleAuditAction Entity. It will perform database oriented actions for + /// a entity of type 'RoleAuditActionEntity'. This DAO works on an EntityFields object. + /// + public partial class RoleAuditActionDAO : DaoBase + { + /// CTor + public RoleAuditActionDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "RoleAuditActionEntity", new RoleAuditActionEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal RoleAuditActionDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling RoleAuditActionCollection object all RoleAuditActionEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity auditActionInstance, IEntity roleInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleAuditActionEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(auditActionInstance, roleInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'RoleAuditActionEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'RoleAuditAction' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to delete + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity auditActionInstance, IEntity roleInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleAuditActionEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(auditActionInstance, roleInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects to update + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity auditActionInstance, IEntity roleInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleAuditActionEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(auditActionInstance, roleInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// AuditActionEntity instance to use as a filter for the RoleAuditActionEntity objects + /// RoleEntity instance to use as a filter for the RoleAuditActionEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity auditActionInstance, IEntity roleInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(auditActionInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)RoleAuditActionFieldIndex.AuditActionID], ComparisonOperator.Equal, ((AuditActionEntity)auditActionInstance).AuditActionID)); + } + if(roleInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)RoleAuditActionFieldIndex.RoleID], ComparisonOperator.Equal, ((RoleEntity)roleInstance).RoleID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/RoleDAO.cs b/DAL/DaoClasses/RoleDAO.cs new file mode 100644 index 0000000..c6b1dbd --- /dev/null +++ b/DAL/DaoClasses/RoleDAO.cs @@ -0,0 +1,251 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the Role Entity. It will perform database oriented actions for + /// a entity of type 'RoleEntity'. This DAO works on an EntityFields object. + /// + public partial class RoleDAO : DaoBase + { + /// CTor + public RoleDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "RoleEntity", new RoleEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal RoleDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves entities of the type 'RoleEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Retrieves in the calling RoleCollection object all RoleEntity objects + /// which are related via a relation of type 'm:n' with the passed in ActionRightEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ActionRightEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingAssignedSystemActionRights(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity actionRightInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(RoleEntity.Relations.RoleSystemActionRightEntityUsingRoleID, "RoleSystemActionRight_"); + relations.Add(RoleSystemActionRightEntity.Relations.ActionRightEntityUsingActionRightID, "RoleSystemActionRight_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(actionRightInstance.Fields[(int)ActionRightFieldIndex.ActionRightID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling RoleCollection object all RoleEntity objects + /// which are related via a relation of type 'm:n' with the passed in ActionRightEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ActionRightEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingAssignedSystemActionRights(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity actionRightInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(RoleEntity.Relations.RoleSystemActionRightEntityUsingRoleID, "RoleSystemActionRight_"); + relations.Add(RoleSystemActionRightEntity.Relations.ActionRightEntityUsingActionRightID, "RoleSystemActionRight_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(actionRightInstance.Fields[(int)ActionRightFieldIndex.ActionRightID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + /// + /// Retrieves in the calling RoleCollection object all RoleEntity objects + /// which are related via a relation of type 'm:n' with the passed in AuditActionEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// AuditActionEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingAssignedAuditActions(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity auditActionInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(RoleEntity.Relations.RoleAuditActionEntityUsingRoleID, "RoleAuditAction_"); + relations.Add(RoleAuditActionEntity.Relations.AuditActionEntityUsingAuditActionID, "RoleAuditAction_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(auditActionInstance.Fields[(int)AuditActionFieldIndex.AuditActionID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling RoleCollection object all RoleEntity objects + /// which are related via a relation of type 'm:n' with the passed in AuditActionEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// AuditActionEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingAssignedAuditActions(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity auditActionInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(RoleEntity.Relations.RoleAuditActionEntityUsingRoleID, "RoleAuditAction_"); + relations.Add(RoleAuditActionEntity.Relations.AuditActionEntityUsingAuditActionID, "RoleAuditAction_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(auditActionInstance.Fields[(int)AuditActionFieldIndex.AuditActionID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + /// + /// Retrieves in the calling RoleCollection object all RoleEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsers(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(RoleEntity.Relations.RoleUserEntityUsingRoleID, "RoleUser_"); + relations.Add(RoleUserEntity.Relations.UserEntityUsingUserID, "RoleUser_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling RoleCollection object all RoleEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsers(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(RoleEntity.Relations.RoleUserEntityUsingRoleID, "RoleUser_"); + relations.Add(RoleUserEntity.Relations.UserEntityUsingUserID, "RoleUser_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/RoleSystemActionRightDAO.cs b/DAL/DaoClasses/RoleSystemActionRightDAO.cs new file mode 100644 index 0000000..aec0335 --- /dev/null +++ b/DAL/DaoClasses/RoleSystemActionRightDAO.cs @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the RoleSystemActionRight Entity. It will perform database oriented actions for + /// a entity of type 'RoleSystemActionRightEntity'. This DAO works on an EntityFields object. + /// + public partial class RoleSystemActionRightDAO : DaoBase + { + /// CTor + public RoleSystemActionRightDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "RoleSystemActionRightEntity", new RoleSystemActionRightEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal RoleSystemActionRightDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling RoleSystemActionRightCollection object all RoleSystemActionRightEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity actionRightInstance, IEntity roleInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleSystemActionRightEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(actionRightInstance, roleInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'RoleSystemActionRightEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'RoleSystemActionRight' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to delete + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity actionRightInstance, IEntity roleInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleSystemActionRightEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(actionRightInstance, roleInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects to update + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity actionRightInstance, IEntity roleInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleSystemActionRightEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(actionRightInstance, roleInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// ActionRightEntity instance to use as a filter for the RoleSystemActionRightEntity objects + /// RoleEntity instance to use as a filter for the RoleSystemActionRightEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity actionRightInstance, IEntity roleInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(actionRightInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)RoleSystemActionRightFieldIndex.ActionRightID], ComparisonOperator.Equal, ((ActionRightEntity)actionRightInstance).ActionRightID)); + } + if(roleInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)RoleSystemActionRightFieldIndex.RoleID], ComparisonOperator.Equal, ((RoleEntity)roleInstance).RoleID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/RoleUserDAO.cs b/DAL/DaoClasses/RoleUserDAO.cs new file mode 100644 index 0000000..5c0b917 --- /dev/null +++ b/DAL/DaoClasses/RoleUserDAO.cs @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the RoleUser Entity. It will perform database oriented actions for + /// a entity of type 'RoleUserEntity'. This DAO works on an EntityFields object. + /// + public partial class RoleUserDAO : DaoBase + { + /// CTor + public RoleUserDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "RoleUserEntity", new RoleUserEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal RoleUserDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling RoleUserCollection object all RoleUserEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to return + /// UserEntity instance to use as a filter for the RoleUserEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity roleInstance, IEntity userInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleUserEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(roleInstance, userInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'RoleUserEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'RoleUser' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to delete + /// UserEntity instance to use as a filter for the RoleUserEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity roleInstance, IEntity userInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleUserEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(roleInstance, userInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// RoleEntity instance to use as a filter for the RoleUserEntity objects to update + /// UserEntity instance to use as a filter for the RoleUserEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity roleInstance, IEntity userInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleUserEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(roleInstance, userInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// RoleEntity instance to use as a filter for the RoleUserEntity objects + /// UserEntity instance to use as a filter for the RoleUserEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity roleInstance, IEntity userInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(roleInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)RoleUserFieldIndex.RoleID], ComparisonOperator.Equal, ((RoleEntity)roleInstance).RoleID)); + } + if(userInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)RoleUserFieldIndex.UserID], ComparisonOperator.Equal, ((UserEntity)userInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/SectionDAO.cs b/DAL/DaoClasses/SectionDAO.cs new file mode 100644 index 0000000..7559b6c --- /dev/null +++ b/DAL/DaoClasses/SectionDAO.cs @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the Section Entity. It will perform database oriented actions for + /// a entity of type 'SectionEntity'. This DAO works on an EntityFields object. + /// + public partial class SectionDAO : DaoBase + { + /// CTor + public SectionDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "SectionEntity", new SectionEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal SectionDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves entities of the type 'SectionEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/SupportQueueDAO.cs b/DAL/DaoClasses/SupportQueueDAO.cs new file mode 100644 index 0000000..af6cf2c --- /dev/null +++ b/DAL/DaoClasses/SupportQueueDAO.cs @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the SupportQueue Entity. It will perform database oriented actions for + /// a entity of type 'SupportQueueEntity'. This DAO works on an EntityFields object. + /// + public partial class SupportQueueDAO : DaoBase + { + /// CTor + public SupportQueueDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "SupportQueueEntity", new SupportQueueEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal SupportQueueDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves entities of the type 'SupportQueueEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/SupportQueueThreadDAO.cs b/DAL/DaoClasses/SupportQueueThreadDAO.cs new file mode 100644 index 0000000..7d59380 --- /dev/null +++ b/DAL/DaoClasses/SupportQueueThreadDAO.cs @@ -0,0 +1,212 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the SupportQueueThread Entity. It will perform database oriented actions for + /// a entity of type 'SupportQueueThreadEntity'. This DAO works on an EntityFields object. + /// + public partial class SupportQueueThreadDAO : DaoBase + { + /// CTor + public SupportQueueThreadDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "SupportQueueThreadEntity", new SupportQueueThreadEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal SupportQueueThreadDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + /// + /// Reads an entity based on a unique constraint. Which entity is read is determined from the passed in fields for the UniqueConstraint. + /// + /// The entity to fetch. Contained data will be overwritten. + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// the PrefetchPath which defines the graph of objects to fetch. + /// The context to fetch the prefetch path with. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + public void FetchSupportQueueThreadUsingUCThreadID(IEntity entityToFetch, ITransaction containingTransaction, System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(entityToFetch.Fields[(int)SupportQueueThreadFieldIndex.ThreadID], ComparisonOperator.Equal, threadID)); + PerformFetchEntityAction(entityToFetch, containingTransaction, selectFilter, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + + + /// + /// Retrieves in the calling SupportQueueThreadCollection object all SupportQueueThreadEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SupportQueueThreadEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'SupportQueueThreadEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'SupportQueueThread' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to delete + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to delete + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SupportQueueThreadEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects to update + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to update + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SupportQueueThreadEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(supportQueueInstance, claimedByUserInstance, placedInQueueByUserInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// SupportQueueEntity instance to use as a filter for the SupportQueueThreadEntity objects + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects + /// UserEntity instance to use as a filter for the SupportQueueThreadEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity supportQueueInstance, IEntity claimedByUserInstance, IEntity placedInQueueByUserInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(supportQueueInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)SupportQueueThreadFieldIndex.QueueID], ComparisonOperator.Equal, ((SupportQueueEntity)supportQueueInstance).QueueID)); + } + if(claimedByUserInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)SupportQueueThreadFieldIndex.ClaimedByUserID], ComparisonOperator.Equal, ((UserEntity)claimedByUserInstance).UserID)); + } + if(placedInQueueByUserInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)SupportQueueThreadFieldIndex.PlacedInQueueByUserID], ComparisonOperator.Equal, ((UserEntity)placedInQueueByUserInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/SystemDataDAO.cs b/DAL/DaoClasses/SystemDataDAO.cs new file mode 100644 index 0000000..df6d74a --- /dev/null +++ b/DAL/DaoClasses/SystemDataDAO.cs @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the SystemData Entity. It will perform database oriented actions for + /// a entity of type 'SystemDataEntity'. This DAO works on an EntityFields object. + /// + public partial class SystemDataDAO : DaoBase + { + /// CTor + public SystemDataDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "SystemDataEntity", new SystemDataEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal SystemDataDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling SystemDataCollection object all SystemDataEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SystemDataEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(roleForAnonymousInstance, roleForNewUserInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'SystemDataEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'SystemData' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to delete + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SystemDataEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(roleForAnonymousInstance, roleForNewUserInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to update + /// RoleEntity instance to use as a filter for the SystemDataEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SystemDataEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(roleForAnonymousInstance, roleForNewUserInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// RoleEntity instance to use as a filter for the SystemDataEntity objects + /// RoleEntity instance to use as a filter for the SystemDataEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity roleForAnonymousInstance, IEntity roleForNewUserInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(roleForAnonymousInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)SystemDataFieldIndex.AnonymousRole], ComparisonOperator.Equal, ((RoleEntity)roleForAnonymousInstance).RoleID)); + } + if(roleForNewUserInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)SystemDataFieldIndex.DefaultRoleNewUser], ComparisonOperator.Equal, ((RoleEntity)roleForNewUserInstance).RoleID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/ThreadDAO.cs b/DAL/DaoClasses/ThreadDAO.cs new file mode 100644 index 0000000..917e1d3 --- /dev/null +++ b/DAL/DaoClasses/ThreadDAO.cs @@ -0,0 +1,333 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the Thread Entity. It will perform database oriented actions for + /// a entity of type 'ThreadEntity'. This DAO works on an EntityFields object. + /// + public partial class ThreadDAO : DaoBase + { + /// CTor + public ThreadDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "ThreadEntity", new ThreadEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal ThreadDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling ThreadCollection object all ThreadEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// ForumEntity instance to use as a filter for the ThreadEntity objects to return + /// UserEntity instance to use as a filter for the ThreadEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity forumInstance, IEntity userWhoStartedThreadInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(forumInstance, userWhoStartedThreadInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'ThreadEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Retrieves in the calling ThreadCollection object all ThreadEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsersWhoSubscribedThread(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ThreadEntity.Relations.ThreadSubscriptionEntityUsingThreadID, "ThreadSubscription_"); + relations.Add(ThreadSubscriptionEntity.Relations.UserEntityUsingUserID, "ThreadSubscription_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling ThreadCollection object all ThreadEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsersWhoSubscribedThread(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ThreadEntity.Relations.ThreadSubscriptionEntityUsingThreadID, "ThreadSubscription_"); + relations.Add(ThreadSubscriptionEntity.Relations.UserEntityUsingUserID, "ThreadSubscription_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + /// + /// Retrieves in the calling ThreadCollection object all ThreadEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsersWhoPostedInThread(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ThreadEntity.Relations.MessageEntityUsingThreadID, "Message_"); + relations.Add(MessageEntity.Relations.UserEntityUsingPostedByUserID, "Message_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling ThreadCollection object all ThreadEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsersWhoPostedInThread(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ThreadEntity.Relations.MessageEntityUsingThreadID, "Message_"); + relations.Add(MessageEntity.Relations.UserEntityUsingPostedByUserID, "Message_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + /// + /// Retrieves in the calling ThreadCollection object all ThreadEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsersWhoBookmarkedThread(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ThreadEntity.Relations.BookmarkEntityUsingThreadID, "Bookmark_"); + relations.Add(BookmarkEntity.Relations.UserEntityUsingUserID, "Bookmark_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling ThreadCollection object all ThreadEntity objects + /// which are related via a relation of type 'm:n' with the passed in UserEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// UserEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingUsersWhoBookmarkedThread(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity userInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(ThreadEntity.Relations.BookmarkEntityUsingThreadID, "Bookmark_"); + relations.Add(BookmarkEntity.Relations.UserEntityUsingUserID, "Bookmark_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(userInstance.Fields[(int)UserFieldIndex.UserID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + + /// + /// Deletes from the persistent storage all 'Thread' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ForumEntity instance to use as a filter for the ThreadEntity objects to delete + /// UserEntity instance to use as a filter for the ThreadEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity forumInstance, IEntity userWhoStartedThreadInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(forumInstance, userWhoStartedThreadInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ForumEntity instance to use as a filter for the ThreadEntity objects to update + /// UserEntity instance to use as a filter for the ThreadEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity forumInstance, IEntity userWhoStartedThreadInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(forumInstance, userWhoStartedThreadInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// ForumEntity instance to use as a filter for the ThreadEntity objects + /// UserEntity instance to use as a filter for the ThreadEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity forumInstance, IEntity userWhoStartedThreadInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(forumInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ThreadFieldIndex.ForumID], ComparisonOperator.Equal, ((ForumEntity)forumInstance).ForumID)); + } + if(userWhoStartedThreadInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ThreadFieldIndex.StartedByUserID], ComparisonOperator.Equal, ((UserEntity)userWhoStartedThreadInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/ThreadSubscriptionDAO.cs b/DAL/DaoClasses/ThreadSubscriptionDAO.cs new file mode 100644 index 0000000..31f7ae1 --- /dev/null +++ b/DAL/DaoClasses/ThreadSubscriptionDAO.cs @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the ThreadSubscription Entity. It will perform database oriented actions for + /// a entity of type 'ThreadSubscriptionEntity'. This DAO works on an EntityFields object. + /// + public partial class ThreadSubscriptionDAO : DaoBase + { + /// CTor + public ThreadSubscriptionDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "ThreadSubscriptionEntity", new ThreadSubscriptionEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal ThreadSubscriptionDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves in the calling ThreadSubscriptionCollection object all ThreadSubscriptionEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity threadInstance, IEntity userInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadSubscriptionEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(threadInstance, userInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'ThreadSubscriptionEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Deletes from the persistent storage all 'ThreadSubscription' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to delete + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity threadInstance, IEntity userInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadSubscriptionEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(threadInstance, userInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects to update + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity threadInstance, IEntity userInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadSubscriptionEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(threadInstance, userInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// ThreadEntity instance to use as a filter for the ThreadSubscriptionEntity objects + /// UserEntity instance to use as a filter for the ThreadSubscriptionEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity threadInstance, IEntity userInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(threadInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ThreadSubscriptionFieldIndex.ThreadID], ComparisonOperator.Equal, ((ThreadEntity)threadInstance).ThreadID)); + } + if(userInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)ThreadSubscriptionFieldIndex.UserID], ComparisonOperator.Equal, ((UserEntity)userInstance).UserID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/TypedListDAO.cs b/DAL/DaoClasses/TypedListDAO.cs new file mode 100644 index 0000000..f38d9d2 --- /dev/null +++ b/DAL/DaoClasses/TypedListDAO.cs @@ -0,0 +1,75 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + /// + /// Generic DAO class for usage with Typed list classes. + /// + public partial class TypedListDAO : DaoBase + { + /// CTor + public TypedListDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, string.Empty, null) + { + } + + /// + /// Retrieves rows in the datatable provided which match the specified filter, containing the fields specified. It will always create a new connection to the database. + /// + /// IEntityFields implementation which forms the definition of the resultset to return. + /// The datatable to fill with the rows retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// Flag to allow duplicate rows or not + /// The list of fields to group by on. When not specified or an empty collection is specified, no group by clause + /// is added to the query. A check is performed for each field in the selectList. If a field in the selectList is not present in the groupByClause collection, an exception is thrown. + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is used to fill the TypedView, which avoids deadlocks on SqlServer. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiAsDataTable(IEntityFields fieldsToReturn, DataTable tableToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, bool allowDuplicates, IGroupByCollection groupByClause, ITransaction transactionToUse, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(fieldsToReturn, tableToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, allowDuplicates, groupByClause, transactionToUse, pageNumber, pageSize); + } + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/UserDAO.cs b/DAL/DaoClasses/UserDAO.cs new file mode 100644 index 0000000..ba37f66 --- /dev/null +++ b/DAL/DaoClasses/UserDAO.cs @@ -0,0 +1,442 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the User Entity. It will perform database oriented actions for + /// a entity of type 'UserEntity'. This DAO works on an EntityFields object. + /// + public partial class UserDAO : DaoBase + { + /// CTor + public UserDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "UserEntity", new UserEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal UserDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + /// + /// Reads an entity based on a unique constraint. Which entity is read is determined from the passed in fields for the UniqueConstraint. + /// + /// The entity to fetch. Contained data will be overwritten. + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// the PrefetchPath which defines the graph of objects to fetch. + /// The context to fetch the prefetch path with. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + public void FetchUserUsingUCNickName(IEntity entityToFetch, ITransaction containingTransaction, System.String nickName, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(entityToFetch.Fields[(int)UserFieldIndex.NickName], ComparisonOperator.Equal, nickName)); + PerformFetchEntityAction(entityToFetch, containingTransaction, selectFilter, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// Extra filter to limit the resultset. Predicate expression can be null, in which case it will be ignored. + /// UserTitleEntity instance to use as a filter for the UserEntity objects to return + /// The page number to retrieve. + /// The page size of the page to retrieve. + public bool GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicateExpression filter, IEntity userTitleInstance, int pageNumber, int pageSize) + { + base.EntityFactoryToUse = entityFactoryToUse; + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + IPredicateExpression selectFilter = CreateFilterUsingForeignKeys(userTitleInstance, fieldsToReturn); + if(filter!=null) + { + selectFilter.AddWithAnd(filter); + } + return base.PerformGetMultiAction(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, selectFilter, null, null, null, pageNumber, pageSize); + } + + /// + /// Retrieves entities of the type 'UserEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in ForumEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ForumEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingStartedThreadsInForums(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity forumInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.ThreadEntityUsingStartedByUserID, "Thread_"); + relations.Add(ThreadEntity.Relations.ForumEntityUsingForumID, "Thread_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(forumInstance.Fields[(int)ForumFieldIndex.ForumID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in ForumEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ForumEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingStartedThreadsInForums(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity forumInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.ThreadEntityUsingStartedByUserID, "Thread_"); + relations.Add(ThreadEntity.Relations.ForumEntityUsingForumID, "Thread_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(forumInstance.Fields[(int)ForumFieldIndex.ForumID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// RoleEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingRoles(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity roleInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.RoleUserEntityUsingUserID, "RoleUser_"); + relations.Add(RoleUserEntity.Relations.RoleEntityUsingRoleID, "RoleUser_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(roleInstance.Fields[(int)RoleFieldIndex.RoleID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in RoleEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// RoleEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingRoles(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity roleInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.RoleUserEntityUsingUserID, "RoleUser_"); + relations.Add(RoleUserEntity.Relations.RoleEntityUsingRoleID, "RoleUser_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(roleInstance.Fields[(int)RoleFieldIndex.RoleID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingThreadCollectionViaThreadSubscription(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity threadInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.ThreadSubscriptionEntityUsingUserID, "ThreadSubscription_"); + relations.Add(ThreadSubscriptionEntity.Relations.ThreadEntityUsingThreadID, "ThreadSubscription_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(threadInstance.Fields[(int)ThreadFieldIndex.ThreadID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ThreadEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingThreadCollectionViaThreadSubscription(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity threadInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.ThreadSubscriptionEntityUsingUserID, "ThreadSubscription_"); + relations.Add(ThreadSubscriptionEntity.Relations.ThreadEntityUsingThreadID, "ThreadSubscription_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(threadInstance.Fields[(int)ThreadFieldIndex.ThreadID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingPostedMessagesInThreads(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity threadInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.MessageEntityUsingPostedByUserID, "Message_"); + relations.Add(MessageEntity.Relations.ThreadEntityUsingThreadID, "Message_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(threadInstance.Fields[(int)ThreadFieldIndex.ThreadID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ThreadEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingPostedMessagesInThreads(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity threadInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.MessageEntityUsingPostedByUserID, "Message_"); + relations.Add(MessageEntity.Relations.ThreadEntityUsingThreadID, "Message_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(threadInstance.Fields[(int)ThreadFieldIndex.ThreadID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ThreadEntity object to be used as a filter in the m:n relation + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if succeeded, false otherwise + public bool GetMultiUsingThreadsInBookmarks(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity threadInstance, int pageNumber, int pageSize) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.BookmarkEntityUsingUserID, "Bookmark_"); + relations.Add(BookmarkEntity.Relations.ThreadEntityUsingThreadID, "Bookmark_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(threadInstance.Fields[(int)ThreadFieldIndex.ThreadID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, pageNumber, pageSize); + } + + /// + /// Retrieves in the calling UserCollection object all UserEntity objects + /// which are related via a relation of type 'm:n' with the passed in ThreadEntity. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// Collection to fill with the entity objects retrieved + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// The EntityFactory to use when creating entity objects during a GetMulti() call. + /// ThreadEntity object to be used as a filter in the m:n relation + /// the PrefetchPath which defines the graph of objects to fetch. + /// true if succeeded, false otherwise + public bool GetMultiUsingThreadsInBookmarks(ITransaction containingTransaction, IEntityCollection collectionToFill, long maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IEntity threadInstance, IPrefetchPath prefetchPathToUse) + { + IEntityFields fieldsToReturn = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + RelationCollection relations = new RelationCollection(); + relations.Add(UserEntity.Relations.BookmarkEntityUsingUserID, "Bookmark_"); + relations.Add(BookmarkEntity.Relations.ThreadEntityUsingThreadID, "Bookmark_", string.Empty, JoinHint.None); + IPredicateExpression selectFilter = new PredicateExpression(); + selectFilter.Add(new FieldCompareValuePredicate(threadInstance.Fields[(int)ThreadFieldIndex.ThreadID], ComparisonOperator.Equal)); + return GetMulti(containingTransaction, collectionToFill, maxNumberOfItemsToReturn, sortClauses, entityFactoryToUse, selectFilter, relations, prefetchPathToUse); + } + + + /// + /// Deletes from the persistent storage all 'User' entities which have data in common + /// with the specified related Entities. If one is omitted, that entity is not used as a filter. + /// + /// A containing transaction, if caller is added to a transaction, or null if not. + /// UserTitleEntity instance to use as a filter for the UserEntity objects to delete + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int DeleteMulti(ITransaction containingTransaction, IEntity userTitleInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + IPredicateExpression deleteFilter = CreateFilterUsingForeignKeys(userTitleInstance, fields); + return base.DeleteMulti(containingTransaction, deleteFilter); + } + + /// + /// Updates all entities of the same type or subtype of the entity entityWithNewValues directly in the persistent storage if they match the filter + /// supplied in filterBucket. Only the fields changed in entityWithNewValues are updated for these fields. Entities of a subtype of the type + /// of entityWithNewValues which are affected by the filterBucket's filter will thus also be updated. + /// + /// IEntity instance which holds the new values for the matching entities to update. Only changed fields are taken into account + /// A containing transaction, if caller is added to a transaction, or null if not. + /// UserTitleEntity instance to use as a filter for the UserEntity objects to update + /// Amount of entities affected, if the used persistent storage has rowcounting enabled. + public int UpdateMulti(IEntity entityWithNewValues, ITransaction containingTransaction, IEntity userTitleInstance) + { + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + IPredicateExpression updateFilter = CreateFilterUsingForeignKeys(userTitleInstance, fields); + return base.UpdateMulti(entityWithNewValues, containingTransaction, updateFilter); + } + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + /// + /// Creates a PredicateExpression which should be used as a filter when any combination of available foreign keys is specified. + /// + /// UserTitleEntity instance to use as a filter for the UserEntity objects + /// IEntityFields implementation which forms the definition of the fieldset of the target entity. + /// A ready to use PredicateExpression based on the passed in foreign key value holders. + private IPredicateExpression CreateFilterUsingForeignKeys(IEntity userTitleInstance, IEntityFields fieldsToReturn) + { + IPredicateExpression selectFilter = new PredicateExpression(); + + if(userTitleInstance != null) + { + selectFilter.Add(new FieldCompareValuePredicate(fieldsToReturn[(int)UserFieldIndex.UserTitleID], ComparisonOperator.Equal, ((UserTitleEntity)userTitleInstance).UserTitleID)); + } + return selectFilter; + } + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/DaoClasses/UserTitleDAO.cs b/DAL/DaoClasses/UserTitleDAO.cs new file mode 100644 index 0000000..456ec97 --- /dev/null +++ b/DAL/DaoClasses/UserTitleDAO.cs @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Collections; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.LLBLGen.Pro.DQE.SqlServer; + + +namespace SD.HnD.DAL.DaoClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// General DAO class for the UserTitle Entity. It will perform database oriented actions for + /// a entity of type 'UserTitleEntity'. This DAO works on an EntityFields object. + /// + public partial class UserTitleDAO : DaoBase + { + /// CTor + public UserTitleDAO() : base(InheritanceInfoProviderSingleton.GetInstance(), new DynamicQueryEngine(), InheritanceHierarchyType.None, "UserTitleEntity", new UserTitleEntityFactory()) + { + } + + /// CTor + /// Inheritance info provider to use. + /// Dqe to use. + /// Type of inheritance. + /// Name of the entity. + /// Entity factory. + internal UserTitleDAO(IInheritanceInfoProvider inheritanceInfoProviderToUse, DynamicQueryEngineBase dqeToUse, InheritanceHierarchyType typeOfInheritance, string entityName, IEntityFactory entityFactory) : base(inheritanceInfoProviderToUse, dqeToUse, typeOfInheritance, entityName, entityFactory) + { + } + + + /// + /// Retrieves entities of the type 'UserTitleEntity' in a datatable which match the specified filter. + /// It will always create a new connection to the database. + /// + /// The maximum number of items to return with this retrieval query. + /// If the used Dynamic Query Engine supports it, 'TOP' is used to limit the amount of rows to return. + /// When set to 0, no limitations are specified. + /// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied. + /// A predicate or predicate expression which should be used as filter for the entities to retrieve. + /// The set of relations to walk to construct to total query. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// a filled datatable if succeeded, false otherwise + public virtual DataTable GetMultiAsDataTable(long maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, int pageNumber, int pageSize) + { + return base.PerformGetMultiAsDataTableAction(maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, pageNumber, pageSize); + } + + + + /// + /// Determines the connection to use. If transaction to use is null, a new connection is created, otherwise the connection of the transaction is used. + /// + /// Transaction to use. + /// a ready to use connection object. + protected override IDbConnection DetermineConnectionToUse(ITransaction transactionToUse) + { + return DbUtils.DetermineConnectionToUse(transactionToUse); + } + + /// + /// Creates a new ADO.NET data adapter. + /// + /// ready to use ADO.NET data-adapter + protected override DbDataAdapter CreateDataAdapter() + { + return DbUtils.CreateDataAdapter(); + } + + + #region Custom DAO code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomDAOCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/ActionRightEntityBase.cs b/DAL/EntityBaseClasses/ActionRightEntityBase.cs new file mode 100644 index 0000000..1b0dc8c --- /dev/null +++ b/DAL/EntityBaseClasses/ActionRightEntityBase.cs @@ -0,0 +1,1061 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'ActionRight'.

+ /// + ///
+ [Serializable] + public abstract partial class ActionRightEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection _forumRoleForumActionRights; + private bool _alwaysFetchForumRoleForumActionRights, _alreadyFetchedForumRoleForumActionRights; + private SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection _roleSystemActionRights; + private bool _alwaysFetchRoleSystemActionRights, _alreadyFetchedRoleSystemActionRights; + private SD.HnD.DAL.CollectionClasses.RoleCollection _systemRightAssignedToRoles; + private bool _alwaysFetchSystemRightAssignedToRoles, _alreadyFetchedSystemRightAssignedToRoles; + + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + + /// Member name ForumRoleForumActionRights + public static readonly string ForumRoleForumActionRights = "ForumRoleForumActionRights"; + /// Member name RoleSystemActionRights + public static readonly string RoleSystemActionRights = "RoleSystemActionRights"; + /// Member name SystemRightAssignedToRoles + public static readonly string SystemRightAssignedToRoles = "SystemRightAssignedToRoles"; + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static ActionRightEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public ActionRightEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for ActionRight which data should be fetched into this ActionRight object + public ActionRightEntityBase(System.Int32 actionRightID) + { + InitClassFetch(actionRightID, null, null); + } + + /// CTor + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ActionRightEntityBase(System.Int32 actionRightID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(actionRightID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// The custom validator object for this ActionRightEntity + public ActionRightEntityBase(System.Int32 actionRightID, IValidator validator) + { + InitClassFetch(actionRightID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected ActionRightEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _forumRoleForumActionRights = (SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection)info.GetValue("_forumRoleForumActionRights", typeof(SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection)); + _alwaysFetchForumRoleForumActionRights = info.GetBoolean("_alwaysFetchForumRoleForumActionRights"); + _alreadyFetchedForumRoleForumActionRights = info.GetBoolean("_alreadyFetchedForumRoleForumActionRights"); + _roleSystemActionRights = (SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection)info.GetValue("_roleSystemActionRights", typeof(SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection)); + _alwaysFetchRoleSystemActionRights = info.GetBoolean("_alwaysFetchRoleSystemActionRights"); + _alreadyFetchedRoleSystemActionRights = info.GetBoolean("_alreadyFetchedRoleSystemActionRights"); + _systemRightAssignedToRoles = (SD.HnD.DAL.CollectionClasses.RoleCollection)info.GetValue("_systemRightAssignedToRoles", typeof(SD.HnD.DAL.CollectionClasses.RoleCollection)); + _alwaysFetchSystemRightAssignedToRoles = info.GetBoolean("_alwaysFetchSystemRightAssignedToRoles"); + _alreadyFetchedSystemRightAssignedToRoles = info.GetBoolean("_alreadyFetchedSystemRightAssignedToRoles"); + + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((ActionRightFieldIndex)fieldIndex) + { + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedForumRoleForumActionRights = (_forumRoleForumActionRights.Count > 0); + _alreadyFetchedRoleSystemActionRights = (_roleSystemActionRights.Count > 0); + _alreadyFetchedSystemRightAssignedToRoles = (_systemRightAssignedToRoles.Count > 0); + + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return ActionRightEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + + case "ForumRoleForumActionRights": + toReturn.Add(ActionRightEntity.Relations.ForumRoleForumActionRightEntityUsingActionRightID); + break; + case "RoleSystemActionRights": + toReturn.Add(ActionRightEntity.Relations.RoleSystemActionRightEntityUsingActionRightID); + break; + case "SystemRightAssignedToRoles": + toReturn.Add(ActionRightEntity.Relations.RoleSystemActionRightEntityUsingActionRightID, "ActionRightEntity__", "RoleSystemActionRight_", JoinHint.None); + toReturn.Add(RoleSystemActionRightEntity.Relations.RoleEntityUsingRoleID, "RoleSystemActionRight_", string.Empty, JoinHint.None); + break; + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_forumRoleForumActionRights", (!this.MarkedForDeletion?_forumRoleForumActionRights:null)); + info.AddValue("_alwaysFetchForumRoleForumActionRights", _alwaysFetchForumRoleForumActionRights); + info.AddValue("_alreadyFetchedForumRoleForumActionRights", _alreadyFetchedForumRoleForumActionRights); + info.AddValue("_roleSystemActionRights", (!this.MarkedForDeletion?_roleSystemActionRights:null)); + info.AddValue("_alwaysFetchRoleSystemActionRights", _alwaysFetchRoleSystemActionRights); + info.AddValue("_alreadyFetchedRoleSystemActionRights", _alreadyFetchedRoleSystemActionRights); + info.AddValue("_systemRightAssignedToRoles", (!this.MarkedForDeletion?_systemRightAssignedToRoles:null)); + info.AddValue("_alwaysFetchSystemRightAssignedToRoles", _alwaysFetchSystemRightAssignedToRoles); + info.AddValue("_alreadyFetchedSystemRightAssignedToRoles", _alreadyFetchedSystemRightAssignedToRoles); + + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + + case "ForumRoleForumActionRights": + _alreadyFetchedForumRoleForumActionRights = true; + if(entity!=null) + { + this.ForumRoleForumActionRights.Add((ForumRoleForumActionRightEntity)entity); + } + break; + case "RoleSystemActionRights": + _alreadyFetchedRoleSystemActionRights = true; + if(entity!=null) + { + this.RoleSystemActionRights.Add((RoleSystemActionRightEntity)entity); + } + break; + case "SystemRightAssignedToRoles": + _alreadyFetchedSystemRightAssignedToRoles = true; + if(entity!=null) + { + this.SystemRightAssignedToRoles.Add((RoleEntity)entity); + } + break; + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + + case "ForumRoleForumActionRights": + _forumRoleForumActionRights.Add((ForumRoleForumActionRightEntity)relatedEntity); + break; + case "RoleSystemActionRights": + _roleSystemActionRights.Add((RoleSystemActionRightEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + + case "ForumRoleForumActionRights": + base.PerformRelatedEntityRemoval(_forumRoleForumActionRights, relatedEntity, signalRelatedEntityManyToOne); + break; + case "RoleSystemActionRights": + base.PerformRelatedEntityRemoval(_roleSystemActionRights, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_forumRoleForumActionRights); + toReturn.Add(_roleSystemActionRights); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 actionRightID) + { + return FetchUsingPK(actionRightID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 actionRightID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(actionRightID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(actionRightID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(actionRightID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.ActionRightID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(ActionRightFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(ActionRightFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new ActionRightRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ForumRoleForumActionRightEntity' + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch) + { + return GetMultiForumRoleForumActionRights(forceFetch, _forumRoleForumActionRights.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ForumRoleForumActionRightEntity' + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IPredicateExpression filter) + { + return GetMultiForumRoleForumActionRights(forceFetch, _forumRoleForumActionRights.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiForumRoleForumActionRights(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedForumRoleForumActionRights || forceFetch || _alwaysFetchForumRoleForumActionRights) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_forumRoleForumActionRights.ParticipatesInTransaction) + { + base.Transaction.Add(_forumRoleForumActionRights); + } + } + _forumRoleForumActionRights.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _forumRoleForumActionRights.EntityFactoryToUse = entityFactoryToUse; + } + _forumRoleForumActionRights.GetMultiManyToOne(this, null, null, filter); + _forumRoleForumActionRights.SuppressClearInGetMulti=false; + _alreadyFetchedForumRoleForumActionRights = true; + } + return _forumRoleForumActionRights; + } + + /// Sets the collection parameters for the collection for 'ForumRoleForumActionRights'. These settings will be taken into account + /// when the property ForumRoleForumActionRights is requested or GetMultiForumRoleForumActionRights is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersForumRoleForumActionRights(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _forumRoleForumActionRights.SortClauses=sortClauses; + _forumRoleForumActionRights.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleSystemActionRightEntity' + public SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection GetMultiRoleSystemActionRights(bool forceFetch) + { + return GetMultiRoleSystemActionRights(forceFetch, _roleSystemActionRights.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'RoleSystemActionRightEntity' + public SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection GetMultiRoleSystemActionRights(bool forceFetch, IPredicateExpression filter) + { + return GetMultiRoleSystemActionRights(forceFetch, _roleSystemActionRights.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection GetMultiRoleSystemActionRights(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiRoleSystemActionRights(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection GetMultiRoleSystemActionRights(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedRoleSystemActionRights || forceFetch || _alwaysFetchRoleSystemActionRights) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_roleSystemActionRights.ParticipatesInTransaction) + { + base.Transaction.Add(_roleSystemActionRights); + } + } + _roleSystemActionRights.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _roleSystemActionRights.EntityFactoryToUse = entityFactoryToUse; + } + _roleSystemActionRights.GetMultiManyToOne(this, null, filter); + _roleSystemActionRights.SuppressClearInGetMulti=false; + _alreadyFetchedRoleSystemActionRights = true; + } + return _roleSystemActionRights; + } + + /// Sets the collection parameters for the collection for 'RoleSystemActionRights'. These settings will be taken into account + /// when the property RoleSystemActionRights is requested or GetMultiRoleSystemActionRights is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersRoleSystemActionRights(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _roleSystemActionRights.SortClauses=sortClauses; + _roleSystemActionRights.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleEntity' + public SD.HnD.DAL.CollectionClasses.RoleCollection GetMultiSystemRightAssignedToRoles(bool forceFetch) + { + return GetMultiSystemRightAssignedToRoles(forceFetch, _systemRightAssignedToRoles.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleCollection GetMultiSystemRightAssignedToRoles(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedSystemRightAssignedToRoles || forceFetch || _alwaysFetchSystemRightAssignedToRoles) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_systemRightAssignedToRoles.ParticipatesInTransaction) + { + base.Transaction.Add(_systemRightAssignedToRoles); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(ActionRightFields.ActionRightID, ComparisonOperator.Equal, this.ActionRightID, "ActionRightEntity__")); + _systemRightAssignedToRoles.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _systemRightAssignedToRoles.EntityFactoryToUse = entityFactoryToUse; + } + _systemRightAssignedToRoles.GetMulti(filter, GetRelationsForField("SystemRightAssignedToRoles")); + _systemRightAssignedToRoles.SuppressClearInGetMulti=false; + _alreadyFetchedSystemRightAssignedToRoles = true; + } + return _systemRightAssignedToRoles; + } + + /// Sets the collection parameters for the collection for 'SystemRightAssignedToRoles'. These settings will be taken into account + /// when the property SystemRightAssignedToRoles is requested or GetMultiSystemRightAssignedToRoles is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersSystemRightAssignedToRoles(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _systemRightAssignedToRoles.SortClauses=sortClauses; + _systemRightAssignedToRoles.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + ActionRightDAO dao = (ActionRightDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _forumRoleForumActionRights.ActiveContext = base.ActiveContext; + _roleSystemActionRights.ActiveContext = base.ActiveContext; + _systemRightAssignedToRoles.ActiveContext = base.ActiveContext; + + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + ActionRightDAO dao = (ActionRightDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + ActionRightDAO dao = (ActionRightDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ActionRightEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + + toReturn.Add("ForumRoleForumActionRights", _forumRoleForumActionRights); + toReturn.Add("RoleSystemActionRights", _roleSystemActionRights); + toReturn.Add("SystemRightAssignedToRoles", _systemRightAssignedToRoles); + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// The validator object for this ActionRightEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 actionRightID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(actionRightID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _forumRoleForumActionRights = new SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection(new ForumRoleForumActionRightEntityFactory()); + _forumRoleForumActionRights.SetContainingEntityInfo(this, "ActionRight"); + _alwaysFetchForumRoleForumActionRights = false; + _alreadyFetchedForumRoleForumActionRights = false; + _roleSystemActionRights = new SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection(new RoleSystemActionRightEntityFactory()); + _roleSystemActionRights.SetContainingEntityInfo(this, "ActionRight"); + _alwaysFetchRoleSystemActionRights = false; + _alreadyFetchedRoleSystemActionRights = false; + _systemRightAssignedToRoles = new SD.HnD.DAL.CollectionClasses.RoleCollection(new RoleEntityFactory()); + _alwaysFetchSystemRightAssignedToRoles = false; + _alreadyFetchedSystemRightAssignedToRoles = false; + + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ActionRightID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ActionRightDescription", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AppliesToForum", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AppliesToSystem", fieldHashtable); + } + #endregion + + + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)ActionRightFieldIndex.ActionRightID].ForcedCurrentValueWrite(actionRightID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateActionRightDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new ActionRightEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static ActionRightRelations Relations + { + get { return new ActionRightRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'ForumRoleForumActionRight' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathForumRoleForumActionRights + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection(), + (IEntityRelation)GetRelationsForField("ForumRoleForumActionRights")[0], (int)SD.HnD.DAL.EntityType.ActionRightEntity, (int)SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity, 0, null, null, null, "ForumRoleForumActionRights", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'RoleSystemActionRight' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoleSystemActionRights + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection(), + (IEntityRelation)GetRelationsForField("RoleSystemActionRights")[0], (int)SD.HnD.DAL.EntityType.ActionRightEntity, (int)SD.HnD.DAL.EntityType.RoleSystemActionRightEntity, 0, null, null, null, "RoleSystemActionRights", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSystemRightAssignedToRoles + { + get + { + IEntityRelation intermediateRelation = ActionRightEntity.Relations.RoleSystemActionRightEntityUsingActionRightID; + intermediateRelation.SetAliases(string.Empty, "RoleSystemActionRight_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.ActionRightEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, GetRelationsForField("SystemRightAssignedToRoles"), "SystemRightAssignedToRoles", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "ActionRightEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return ActionRightEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return ActionRightEntity.FieldsCustomProperties;} + } + + /// The ActionRightID property of the Entity ActionRight

+ ///
+ /// Mapped on table field: "ActionRight"."ActionRightID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 ActionRightID + { + get { return (System.Int32)GetValue((int)ActionRightFieldIndex.ActionRightID, true); } + set { SetValue((int)ActionRightFieldIndex.ActionRightID, value, true); } + } + /// The ActionRightDescription property of the Entity ActionRight

+ ///
+ /// Mapped on table field: "ActionRight"."ActionRightDescription"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 50
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String ActionRightDescription + { + get { return (System.String)GetValue((int)ActionRightFieldIndex.ActionRightDescription, true); } + set { SetValue((int)ActionRightFieldIndex.ActionRightDescription, value, true); } + } + /// The AppliesToForum property of the Entity ActionRight

+ ///
+ /// Mapped on table field: "ActionRight"."AppliesToForum"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean AppliesToForum + { + get { return (System.Boolean)GetValue((int)ActionRightFieldIndex.AppliesToForum, true); } + set { SetValue((int)ActionRightFieldIndex.AppliesToForum, value, true); } + } + /// The AppliesToSystem property of the Entity ActionRight

+ ///
+ /// Mapped on table field: "ActionRight"."AppliesToSystem"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean AppliesToSystem + { + get { return (System.Boolean)GetValue((int)ActionRightFieldIndex.AppliesToSystem, true); } + set { SetValue((int)ActionRightFieldIndex.AppliesToSystem, value, true); } + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiForumRoleForumActionRights()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection ForumRoleForumActionRights + { + get { return GetMultiForumRoleForumActionRights(false); } + } + + /// Gets / sets the lazy loading flag for ForumRoleForumActionRights. When set to true, ForumRoleForumActionRights is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ForumRoleForumActionRights is accessed. You can always execute + /// a forced fetch by calling GetMultiForumRoleForumActionRights(true). + [Browsable(false)] + public bool AlwaysFetchForumRoleForumActionRights + { + get { return _alwaysFetchForumRoleForumActionRights; } + set { _alwaysFetchForumRoleForumActionRights = value; } + } + + /// Gets / Sets the lazy loading flag if the property ForumRoleForumActionRights already has been fetched. Setting this property to false when ForumRoleForumActionRights has been fetched + /// will clear the ForumRoleForumActionRights collection well. Setting this property to true while ForumRoleForumActionRights hasn't been fetched disables lazy loading for ForumRoleForumActionRights + [Browsable(false)] + public bool AlreadyFetchedForumRoleForumActionRights + { + get { return _alreadyFetchedForumRoleForumActionRights;} + set + { + if(_alreadyFetchedForumRoleForumActionRights && !value && (_forumRoleForumActionRights != null)) + { + _forumRoleForumActionRights.Clear(); + } + _alreadyFetchedForumRoleForumActionRights = value; + } + } + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiRoleSystemActionRights()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection RoleSystemActionRights + { + get { return GetMultiRoleSystemActionRights(false); } + } + + /// Gets / sets the lazy loading flag for RoleSystemActionRights. When set to true, RoleSystemActionRights is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RoleSystemActionRights is accessed. You can always execute + /// a forced fetch by calling GetMultiRoleSystemActionRights(true). + [Browsable(false)] + public bool AlwaysFetchRoleSystemActionRights + { + get { return _alwaysFetchRoleSystemActionRights; } + set { _alwaysFetchRoleSystemActionRights = value; } + } + + /// Gets / Sets the lazy loading flag if the property RoleSystemActionRights already has been fetched. Setting this property to false when RoleSystemActionRights has been fetched + /// will clear the RoleSystemActionRights collection well. Setting this property to true while RoleSystemActionRights hasn't been fetched disables lazy loading for RoleSystemActionRights + [Browsable(false)] + public bool AlreadyFetchedRoleSystemActionRights + { + get { return _alreadyFetchedRoleSystemActionRights;} + set + { + if(_alreadyFetchedRoleSystemActionRights && !value && (_roleSystemActionRights != null)) + { + _roleSystemActionRights.Clear(); + } + _alreadyFetchedRoleSystemActionRights = value; + } + } + + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiSystemRightAssignedToRoles()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleCollection SystemRightAssignedToRoles + { + get { return GetMultiSystemRightAssignedToRoles(false); } + } + + /// Gets / sets the lazy loading flag for SystemRightAssignedToRoles. When set to true, SystemRightAssignedToRoles is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SystemRightAssignedToRoles is accessed. You can always execute + /// a forced fetch by calling GetMultiSystemRightAssignedToRoles(true). + [Browsable(false)] + public bool AlwaysFetchSystemRightAssignedToRoles + { + get { return _alwaysFetchSystemRightAssignedToRoles; } + set { _alwaysFetchSystemRightAssignedToRoles = value; } + } + + /// Gets / Sets the lazy loading flag if the property SystemRightAssignedToRoles already has been fetched. Setting this property to false when SystemRightAssignedToRoles has been fetched + /// will clear the SystemRightAssignedToRoles collection well. Setting this property to true while SystemRightAssignedToRoles hasn't been fetched disables lazy loading for SystemRightAssignedToRoles + [Browsable(false)] + public bool AlreadyFetchedSystemRightAssignedToRoles + { + get { return _alreadyFetchedSystemRightAssignedToRoles;} + set + { + if(_alreadyFetchedSystemRightAssignedToRoles && !value && (_systemRightAssignedToRoles != null)) + { + _systemRightAssignedToRoles.Clear(); + } + _alreadyFetchedSystemRightAssignedToRoles = value; + } + } + + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.ActionRightEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/AttachmentEntityBase.cs b/DAL/EntityBaseClasses/AttachmentEntityBase.cs new file mode 100644 index 0000000..c50abc5 --- /dev/null +++ b/DAL/EntityBaseClasses/AttachmentEntityBase.cs @@ -0,0 +1,924 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'Attachment'.

+ /// + ///
+ [Serializable] + public abstract partial class AttachmentEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private MessageEntity _belongsToMessage; + private bool _alwaysFetchBelongsToMessage, _alreadyFetchedBelongsToMessage, _belongsToMessageReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name BelongsToMessage + public static readonly string BelongsToMessage = "BelongsToMessage"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static AttachmentEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public AttachmentEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for Attachment which data should be fetched into this Attachment object + public AttachmentEntityBase(System.Int32 attachmentID) + { + InitClassFetch(attachmentID, null, null); + } + + /// CTor + /// PK value for Attachment which data should be fetched into this Attachment object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AttachmentEntityBase(System.Int32 attachmentID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(attachmentID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for Attachment which data should be fetched into this Attachment object + /// The custom validator object for this AttachmentEntity + public AttachmentEntityBase(System.Int32 attachmentID, IValidator validator) + { + InitClassFetch(attachmentID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected AttachmentEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _belongsToMessage = (MessageEntity)info.GetValue("_belongsToMessage", typeof(MessageEntity)); + if(_belongsToMessage!=null) + { + _belongsToMessage.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _belongsToMessageReturnsNewIfNotFound = info.GetBoolean("_belongsToMessageReturnsNewIfNotFound"); + _alwaysFetchBelongsToMessage = info.GetBoolean("_alwaysFetchBelongsToMessage"); + _alreadyFetchedBelongsToMessage = info.GetBoolean("_alreadyFetchedBelongsToMessage"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((AttachmentFieldIndex)fieldIndex) + { + case AttachmentFieldIndex.MessageID: + DesetupSyncBelongsToMessage(true, false); + _alreadyFetchedBelongsToMessage = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedBelongsToMessage = (_belongsToMessage != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return AttachmentEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "BelongsToMessage": + toReturn.Add(AttachmentEntity.Relations.MessageEntityUsingMessageID); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_belongsToMessage", (!this.MarkedForDeletion?_belongsToMessage:null)); + info.AddValue("_belongsToMessageReturnsNewIfNotFound", _belongsToMessageReturnsNewIfNotFound); + info.AddValue("_alwaysFetchBelongsToMessage", _alwaysFetchBelongsToMessage); + info.AddValue("_alreadyFetchedBelongsToMessage", _alreadyFetchedBelongsToMessage); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "BelongsToMessage": + _alreadyFetchedBelongsToMessage = true; + this.BelongsToMessage = (MessageEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "BelongsToMessage": + SetupSyncBelongsToMessage(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "BelongsToMessage": + DesetupSyncBelongsToMessage(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_belongsToMessage!=null) + { + toReturn.Add(_belongsToMessage); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Attachment which data should be fetched into this Attachment object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 attachmentID) + { + return FetchUsingPK(attachmentID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Attachment which data should be fetched into this Attachment object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 attachmentID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(attachmentID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Attachment which data should be fetched into this Attachment object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 attachmentID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(attachmentID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Attachment which data should be fetched into this Attachment object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 attachmentID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(attachmentID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.AttachmentID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(AttachmentFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(AttachmentFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new AttachmentRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'MessageEntity', using a relation of type 'n:1' + /// A fetched entity of type 'MessageEntity' which is related to this entity. + public MessageEntity GetSingleBelongsToMessage() + { + return GetSingleBelongsToMessage(false); + } + + /// Retrieves the related entity of type 'MessageEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'MessageEntity' which is related to this entity. + public virtual MessageEntity GetSingleBelongsToMessage(bool forceFetch) + { + if( ( !_alreadyFetchedBelongsToMessage || forceFetch || _alwaysFetchBelongsToMessage) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(AttachmentEntity.Relations.MessageEntityUsingMessageID); + + MessageEntity newEntity = new MessageEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.MessageID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (MessageEntity)base.ActiveContext.Get(newEntity); + } + this.BelongsToMessage = newEntity; + } + else + { + if(_belongsToMessageReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_belongsToMessage == null))) + { + this.BelongsToMessage = newEntity; + } + } + else + { + this.BelongsToMessage = null; + } + } + _alreadyFetchedBelongsToMessage = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _belongsToMessage; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + AttachmentDAO dao = (AttachmentDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_belongsToMessage!=null) + { + _belongsToMessage.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + AttachmentDAO dao = (AttachmentDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + AttachmentDAO dao = (AttachmentDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AttachmentEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("BelongsToMessage", _belongsToMessage); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for Attachment which data should be fetched into this Attachment object + /// The validator object for this AttachmentEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 attachmentID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(attachmentID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _belongsToMessage = null; + _belongsToMessageReturnsNewIfNotFound = true; + _alwaysFetchBelongsToMessage = false; + _alreadyFetchedBelongsToMessage = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AttachmentID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MessageID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Filename", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Approved", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Filecontents", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Filesize", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AddedOn", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _belongsToMessage + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncBelongsToMessage(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _belongsToMessage, new PropertyChangedEventHandler( OnBelongsToMessagePropertyChanged ), "BelongsToMessage", AttachmentEntity.Relations.MessageEntityUsingMessageID, true, signalRelatedEntity, "Attachments", resetFKFields, new int[] { (int)AttachmentFieldIndex.MessageID } ); + _belongsToMessage = null; + } + + /// setups the sync logic for member _belongsToMessage + /// Instance to set as the related entity of type entityType + private void SetupSyncBelongsToMessage(IEntity relatedEntity) + { + if(_belongsToMessage!=relatedEntity) + { + DesetupSyncBelongsToMessage(true, true); + _belongsToMessage = (MessageEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _belongsToMessage, new PropertyChangedEventHandler( OnBelongsToMessagePropertyChanged ), "BelongsToMessage", AttachmentEntity.Relations.MessageEntityUsingMessageID, true, ref _alreadyFetchedBelongsToMessage, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnBelongsToMessagePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for Attachment which data should be fetched into this Attachment object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 attachmentID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)AttachmentFieldIndex.AttachmentID].ForcedCurrentValueWrite(attachmentID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAttachmentDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new AttachmentEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static AttachmentRelations Relations + { + get { return new AttachmentRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Message' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathBelongsToMessage + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.MessageCollection(), + (IEntityRelation)GetRelationsForField("BelongsToMessage")[0], (int)SD.HnD.DAL.EntityType.AttachmentEntity, (int)SD.HnD.DAL.EntityType.MessageEntity, 0, null, null, null, "BelongsToMessage", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "AttachmentEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return AttachmentEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return AttachmentEntity.FieldsCustomProperties;} + } + + /// The AttachmentID property of the Entity Attachment

+ ///
+ /// Mapped on table field: "Attachment"."AttachmentID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 AttachmentID + { + get { return (System.Int32)GetValue((int)AttachmentFieldIndex.AttachmentID, true); } + set { SetValue((int)AttachmentFieldIndex.AttachmentID, value, true); } + } + /// The MessageID property of the Entity Attachment

+ ///
+ /// Mapped on table field: "Attachment"."MessageID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 MessageID + { + get { return (System.Int32)GetValue((int)AttachmentFieldIndex.MessageID, true); } + set { SetValue((int)AttachmentFieldIndex.MessageID, value, true); } + } + /// The Filename property of the Entity Attachment

+ ///
+ /// Mapped on table field: "Attachment"."Filename"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 255
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String Filename + { + get { return (System.String)GetValue((int)AttachmentFieldIndex.Filename, true); } + set { SetValue((int)AttachmentFieldIndex.Filename, value, true); } + } + /// The Approved property of the Entity Attachment

+ ///
+ /// Mapped on table field: "Attachment"."Approved"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean Approved + { + get { return (System.Boolean)GetValue((int)AttachmentFieldIndex.Approved, true); } + set { SetValue((int)AttachmentFieldIndex.Approved, value, true); } + } + /// The Filecontents property of the Entity Attachment

+ ///
+ /// Mapped on table field: "Attachment"."Filecontents"
+ /// Table field type characteristics (type, precision, scale, length): Image, 0, 0, 2147483647
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Byte[] Filecontents + { + get { return (System.Byte[])GetValue((int)AttachmentFieldIndex.Filecontents, true); } + set { SetValue((int)AttachmentFieldIndex.Filecontents, value, true); } + } + /// The Filesize property of the Entity Attachment

+ ///
+ /// Mapped on table field: "Attachment"."Filesize"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 Filesize + { + get { return (System.Int32)GetValue((int)AttachmentFieldIndex.Filesize, true); } + set { SetValue((int)AttachmentFieldIndex.Filesize, value, true); } + } + /// The AddedOn property of the Entity Attachment

+ ///
+ /// Mapped on table field: "Attachment"."AddedOn"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.DateTime AddedOn + { + get { return (System.DateTime)GetValue((int)AttachmentFieldIndex.AddedOn, true); } + set { SetValue((int)AttachmentFieldIndex.AddedOn, value, true); } + } + + + + /// Gets / sets related entity of type 'MessageEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleBelongsToMessage()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual MessageEntity BelongsToMessage + { + get { return GetSingleBelongsToMessage(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncBelongsToMessage(value); + } + else + { + if(value==null) + { + if(_belongsToMessage != null) + { + _belongsToMessage.UnsetRelatedEntity(this, "Attachments"); + } + } + else + { + if(_belongsToMessage!=value) + { + ((IEntity)value).SetRelatedEntity(this, "Attachments"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for BelongsToMessage. When set to true, BelongsToMessage is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time BelongsToMessage is accessed. You can always execute + /// a forced fetch by calling GetSingleBelongsToMessage(true). + [Browsable(false)] + public bool AlwaysFetchBelongsToMessage + { + get { return _alwaysFetchBelongsToMessage; } + set { _alwaysFetchBelongsToMessage = value; } + } + + /// Gets / Sets the lazy loading flag if the property BelongsToMessage already has been fetched. Setting this property to false when BelongsToMessage has been fetched + /// will set BelongsToMessage to null as well. Setting this property to true while BelongsToMessage hasn't been fetched disables lazy loading for BelongsToMessage + [Browsable(false)] + public bool AlreadyFetchedBelongsToMessage + { + get { return _alreadyFetchedBelongsToMessage;} + set + { + if(_alreadyFetchedBelongsToMessage && !value) + { + this.BelongsToMessage = null; + } + _alreadyFetchedBelongsToMessage = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property BelongsToMessage is not found + /// in the database. When set to true, BelongsToMessage will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool BelongsToMessageReturnsNewIfNotFound + { + get { return _belongsToMessageReturnsNewIfNotFound; } + set { _belongsToMessageReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.AttachmentEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/AuditActionEntityBase.cs b/DAL/EntityBaseClasses/AuditActionEntityBase.cs new file mode 100644 index 0000000..ffa3df6 --- /dev/null +++ b/DAL/EntityBaseClasses/AuditActionEntityBase.cs @@ -0,0 +1,1035 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'AuditAction'.

+ /// + ///
+ [Serializable] + public abstract partial class AuditActionEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection _auditDataCore; + private bool _alwaysFetchAuditDataCore, _alreadyFetchedAuditDataCore; + private SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection _roleAuditActions; + private bool _alwaysFetchRoleAuditActions, _alreadyFetchedRoleAuditActions; + private SD.HnD.DAL.CollectionClasses.RoleCollection _rolesWithAuditAction; + private bool _alwaysFetchRolesWithAuditAction, _alreadyFetchedRolesWithAuditAction; + + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + + /// Member name AuditDataCore + public static readonly string AuditDataCore = "AuditDataCore"; + /// Member name RoleAuditActions + public static readonly string RoleAuditActions = "RoleAuditActions"; + /// Member name RolesWithAuditAction + public static readonly string RolesWithAuditAction = "RolesWithAuditAction"; + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static AuditActionEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public AuditActionEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for AuditAction which data should be fetched into this AuditAction object + public AuditActionEntityBase(System.Int32 auditActionID) + { + InitClassFetch(auditActionID, null, null); + } + + /// CTor + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AuditActionEntityBase(System.Int32 auditActionID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(auditActionID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// The custom validator object for this AuditActionEntity + public AuditActionEntityBase(System.Int32 auditActionID, IValidator validator) + { + InitClassFetch(auditActionID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected AuditActionEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _auditDataCore = (SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection)info.GetValue("_auditDataCore", typeof(SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection)); + _alwaysFetchAuditDataCore = info.GetBoolean("_alwaysFetchAuditDataCore"); + _alreadyFetchedAuditDataCore = info.GetBoolean("_alreadyFetchedAuditDataCore"); + _roleAuditActions = (SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection)info.GetValue("_roleAuditActions", typeof(SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection)); + _alwaysFetchRoleAuditActions = info.GetBoolean("_alwaysFetchRoleAuditActions"); + _alreadyFetchedRoleAuditActions = info.GetBoolean("_alreadyFetchedRoleAuditActions"); + _rolesWithAuditAction = (SD.HnD.DAL.CollectionClasses.RoleCollection)info.GetValue("_rolesWithAuditAction", typeof(SD.HnD.DAL.CollectionClasses.RoleCollection)); + _alwaysFetchRolesWithAuditAction = info.GetBoolean("_alwaysFetchRolesWithAuditAction"); + _alreadyFetchedRolesWithAuditAction = info.GetBoolean("_alreadyFetchedRolesWithAuditAction"); + + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((AuditActionFieldIndex)fieldIndex) + { + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedAuditDataCore = (_auditDataCore.Count > 0); + _alreadyFetchedRoleAuditActions = (_roleAuditActions.Count > 0); + _alreadyFetchedRolesWithAuditAction = (_rolesWithAuditAction.Count > 0); + + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return AuditActionEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + + case "AuditDataCore": + toReturn.Add(AuditActionEntity.Relations.AuditDataCoreEntityUsingAuditActionID); + break; + case "RoleAuditActions": + toReturn.Add(AuditActionEntity.Relations.RoleAuditActionEntityUsingAuditActionID); + break; + case "RolesWithAuditAction": + toReturn.Add(AuditActionEntity.Relations.RoleAuditActionEntityUsingAuditActionID, "AuditActionEntity__", "RoleAuditAction_", JoinHint.None); + toReturn.Add(RoleAuditActionEntity.Relations.RoleEntityUsingRoleID, "RoleAuditAction_", string.Empty, JoinHint.None); + break; + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_auditDataCore", (!this.MarkedForDeletion?_auditDataCore:null)); + info.AddValue("_alwaysFetchAuditDataCore", _alwaysFetchAuditDataCore); + info.AddValue("_alreadyFetchedAuditDataCore", _alreadyFetchedAuditDataCore); + info.AddValue("_roleAuditActions", (!this.MarkedForDeletion?_roleAuditActions:null)); + info.AddValue("_alwaysFetchRoleAuditActions", _alwaysFetchRoleAuditActions); + info.AddValue("_alreadyFetchedRoleAuditActions", _alreadyFetchedRoleAuditActions); + info.AddValue("_rolesWithAuditAction", (!this.MarkedForDeletion?_rolesWithAuditAction:null)); + info.AddValue("_alwaysFetchRolesWithAuditAction", _alwaysFetchRolesWithAuditAction); + info.AddValue("_alreadyFetchedRolesWithAuditAction", _alreadyFetchedRolesWithAuditAction); + + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + + case "AuditDataCore": + _alreadyFetchedAuditDataCore = true; + if(entity!=null) + { + this.AuditDataCore.Add((AuditDataCoreEntity)entity); + } + break; + case "RoleAuditActions": + _alreadyFetchedRoleAuditActions = true; + if(entity!=null) + { + this.RoleAuditActions.Add((RoleAuditActionEntity)entity); + } + break; + case "RolesWithAuditAction": + _alreadyFetchedRolesWithAuditAction = true; + if(entity!=null) + { + this.RolesWithAuditAction.Add((RoleEntity)entity); + } + break; + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + + case "AuditDataCore": + _auditDataCore.Add((AuditDataCoreEntity)relatedEntity); + break; + case "RoleAuditActions": + _roleAuditActions.Add((RoleAuditActionEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + + case "AuditDataCore": + base.PerformRelatedEntityRemoval(_auditDataCore, relatedEntity, signalRelatedEntityManyToOne); + break; + case "RoleAuditActions": + base.PerformRelatedEntityRemoval(_roleAuditActions, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_auditDataCore); + toReturn.Add(_roleAuditActions); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditActionID) + { + return FetchUsingPK(auditActionID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditActionID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(auditActionID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditActionID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(auditActionID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditActionID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(auditActionID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.AuditActionID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(AuditActionFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(AuditActionFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new AuditActionRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'AuditDataCoreEntity' + public SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection GetMultiAuditDataCore(bool forceFetch) + { + return GetMultiAuditDataCore(forceFetch, _auditDataCore.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'AuditDataCoreEntity' + public SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection GetMultiAuditDataCore(bool forceFetch, IPredicateExpression filter) + { + return GetMultiAuditDataCore(forceFetch, _auditDataCore.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection GetMultiAuditDataCore(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiAuditDataCore(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection GetMultiAuditDataCore(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedAuditDataCore || forceFetch || _alwaysFetchAuditDataCore) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_auditDataCore.ParticipatesInTransaction) + { + base.Transaction.Add(_auditDataCore); + } + } + _auditDataCore.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _auditDataCore.EntityFactoryToUse = entityFactoryToUse; + } + _auditDataCore.GetMultiManyToOne(this, null, filter); + _auditDataCore.SuppressClearInGetMulti=false; + _alreadyFetchedAuditDataCore = true; + } + return _auditDataCore; + } + + /// Sets the collection parameters for the collection for 'AuditDataCore'. These settings will be taken into account + /// when the property AuditDataCore is requested or GetMultiAuditDataCore is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersAuditDataCore(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _auditDataCore.SortClauses=sortClauses; + _auditDataCore.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleAuditActionEntity' + public SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection GetMultiRoleAuditActions(bool forceFetch) + { + return GetMultiRoleAuditActions(forceFetch, _roleAuditActions.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'RoleAuditActionEntity' + public SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection GetMultiRoleAuditActions(bool forceFetch, IPredicateExpression filter) + { + return GetMultiRoleAuditActions(forceFetch, _roleAuditActions.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection GetMultiRoleAuditActions(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiRoleAuditActions(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection GetMultiRoleAuditActions(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedRoleAuditActions || forceFetch || _alwaysFetchRoleAuditActions) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_roleAuditActions.ParticipatesInTransaction) + { + base.Transaction.Add(_roleAuditActions); + } + } + _roleAuditActions.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _roleAuditActions.EntityFactoryToUse = entityFactoryToUse; + } + _roleAuditActions.GetMultiManyToOne(this, null, filter); + _roleAuditActions.SuppressClearInGetMulti=false; + _alreadyFetchedRoleAuditActions = true; + } + return _roleAuditActions; + } + + /// Sets the collection parameters for the collection for 'RoleAuditActions'. These settings will be taken into account + /// when the property RoleAuditActions is requested or GetMultiRoleAuditActions is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersRoleAuditActions(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _roleAuditActions.SortClauses=sortClauses; + _roleAuditActions.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleEntity' + public SD.HnD.DAL.CollectionClasses.RoleCollection GetMultiRolesWithAuditAction(bool forceFetch) + { + return GetMultiRolesWithAuditAction(forceFetch, _rolesWithAuditAction.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleCollection GetMultiRolesWithAuditAction(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedRolesWithAuditAction || forceFetch || _alwaysFetchRolesWithAuditAction) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_rolesWithAuditAction.ParticipatesInTransaction) + { + base.Transaction.Add(_rolesWithAuditAction); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(AuditActionFields.AuditActionID, ComparisonOperator.Equal, this.AuditActionID, "AuditActionEntity__")); + _rolesWithAuditAction.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _rolesWithAuditAction.EntityFactoryToUse = entityFactoryToUse; + } + _rolesWithAuditAction.GetMulti(filter, GetRelationsForField("RolesWithAuditAction")); + _rolesWithAuditAction.SuppressClearInGetMulti=false; + _alreadyFetchedRolesWithAuditAction = true; + } + return _rolesWithAuditAction; + } + + /// Sets the collection parameters for the collection for 'RolesWithAuditAction'. These settings will be taken into account + /// when the property RolesWithAuditAction is requested or GetMultiRolesWithAuditAction is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersRolesWithAuditAction(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _rolesWithAuditAction.SortClauses=sortClauses; + _rolesWithAuditAction.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + AuditActionDAO dao = (AuditActionDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _auditDataCore.ActiveContext = base.ActiveContext; + _roleAuditActions.ActiveContext = base.ActiveContext; + _rolesWithAuditAction.ActiveContext = base.ActiveContext; + + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + AuditActionDAO dao = (AuditActionDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + AuditActionDAO dao = (AuditActionDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditActionEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + + toReturn.Add("AuditDataCore", _auditDataCore); + toReturn.Add("RoleAuditActions", _roleAuditActions); + toReturn.Add("RolesWithAuditAction", _rolesWithAuditAction); + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// The validator object for this AuditActionEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 auditActionID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(auditActionID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _auditDataCore = new SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection(new AuditDataCoreEntityFactory()); + _auditDataCore.SetContainingEntityInfo(this, "AuditAction"); + _alwaysFetchAuditDataCore = false; + _alreadyFetchedAuditDataCore = false; + _roleAuditActions = new SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection(new RoleAuditActionEntityFactory()); + _roleAuditActions.SetContainingEntityInfo(this, "AuditAction"); + _alwaysFetchRoleAuditActions = false; + _alreadyFetchedRoleAuditActions = false; + _rolesWithAuditAction = new SD.HnD.DAL.CollectionClasses.RoleCollection(new RoleEntityFactory()); + _alwaysFetchRolesWithAuditAction = false; + _alreadyFetchedRolesWithAuditAction = false; + + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AuditActionID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AuditActionDescription", fieldHashtable); + } + #endregion + + + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 auditActionID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)AuditActionFieldIndex.AuditActionID].ForcedCurrentValueWrite(auditActionID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAuditActionDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new AuditActionEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static AuditActionRelations Relations + { + get { return new AuditActionRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'AuditDataCore' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathAuditDataCore + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection(), + (IEntityRelation)GetRelationsForField("AuditDataCore")[0], (int)SD.HnD.DAL.EntityType.AuditActionEntity, (int)SD.HnD.DAL.EntityType.AuditDataCoreEntity, 0, null, null, null, "AuditDataCore", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'RoleAuditAction' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoleAuditActions + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection(), + (IEntityRelation)GetRelationsForField("RoleAuditActions")[0], (int)SD.HnD.DAL.EntityType.AuditActionEntity, (int)SD.HnD.DAL.EntityType.RoleAuditActionEntity, 0, null, null, null, "RoleAuditActions", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRolesWithAuditAction + { + get + { + IEntityRelation intermediateRelation = AuditActionEntity.Relations.RoleAuditActionEntityUsingAuditActionID; + intermediateRelation.SetAliases(string.Empty, "RoleAuditAction_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.AuditActionEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, GetRelationsForField("RolesWithAuditAction"), "RolesWithAuditAction", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "AuditActionEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return AuditActionEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return AuditActionEntity.FieldsCustomProperties;} + } + + /// The AuditActionID property of the Entity AuditAction

+ ///
+ /// Mapped on table field: "AuditAction"."AuditActionID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 AuditActionID + { + get { return (System.Int32)GetValue((int)AuditActionFieldIndex.AuditActionID, true); } + set { SetValue((int)AuditActionFieldIndex.AuditActionID, value, true); } + } + /// The AuditActionDescription property of the Entity AuditAction

+ ///
+ /// Mapped on table field: "AuditAction"."AuditActionDescription"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 50
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String AuditActionDescription + { + get { return (System.String)GetValue((int)AuditActionFieldIndex.AuditActionDescription, true); } + set { SetValue((int)AuditActionFieldIndex.AuditActionDescription, value, true); } + } + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiAuditDataCore()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection AuditDataCore + { + get { return GetMultiAuditDataCore(false); } + } + + /// Gets / sets the lazy loading flag for AuditDataCore. When set to true, AuditDataCore is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time AuditDataCore is accessed. You can always execute + /// a forced fetch by calling GetMultiAuditDataCore(true). + [Browsable(false)] + public bool AlwaysFetchAuditDataCore + { + get { return _alwaysFetchAuditDataCore; } + set { _alwaysFetchAuditDataCore = value; } + } + + /// Gets / Sets the lazy loading flag if the property AuditDataCore already has been fetched. Setting this property to false when AuditDataCore has been fetched + /// will clear the AuditDataCore collection well. Setting this property to true while AuditDataCore hasn't been fetched disables lazy loading for AuditDataCore + [Browsable(false)] + public bool AlreadyFetchedAuditDataCore + { + get { return _alreadyFetchedAuditDataCore;} + set + { + if(_alreadyFetchedAuditDataCore && !value && (_auditDataCore != null)) + { + _auditDataCore.Clear(); + } + _alreadyFetchedAuditDataCore = value; + } + } + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiRoleAuditActions()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection RoleAuditActions + { + get { return GetMultiRoleAuditActions(false); } + } + + /// Gets / sets the lazy loading flag for RoleAuditActions. When set to true, RoleAuditActions is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RoleAuditActions is accessed. You can always execute + /// a forced fetch by calling GetMultiRoleAuditActions(true). + [Browsable(false)] + public bool AlwaysFetchRoleAuditActions + { + get { return _alwaysFetchRoleAuditActions; } + set { _alwaysFetchRoleAuditActions = value; } + } + + /// Gets / Sets the lazy loading flag if the property RoleAuditActions already has been fetched. Setting this property to false when RoleAuditActions has been fetched + /// will clear the RoleAuditActions collection well. Setting this property to true while RoleAuditActions hasn't been fetched disables lazy loading for RoleAuditActions + [Browsable(false)] + public bool AlreadyFetchedRoleAuditActions + { + get { return _alreadyFetchedRoleAuditActions;} + set + { + if(_alreadyFetchedRoleAuditActions && !value && (_roleAuditActions != null)) + { + _roleAuditActions.Clear(); + } + _alreadyFetchedRoleAuditActions = value; + } + } + + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiRolesWithAuditAction()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleCollection RolesWithAuditAction + { + get { return GetMultiRolesWithAuditAction(false); } + } + + /// Gets / sets the lazy loading flag for RolesWithAuditAction. When set to true, RolesWithAuditAction is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RolesWithAuditAction is accessed. You can always execute + /// a forced fetch by calling GetMultiRolesWithAuditAction(true). + [Browsable(false)] + public bool AlwaysFetchRolesWithAuditAction + { + get { return _alwaysFetchRolesWithAuditAction; } + set { _alwaysFetchRolesWithAuditAction = value; } + } + + /// Gets / Sets the lazy loading flag if the property RolesWithAuditAction already has been fetched. Setting this property to false when RolesWithAuditAction has been fetched + /// will clear the RolesWithAuditAction collection well. Setting this property to true while RolesWithAuditAction hasn't been fetched disables lazy loading for RolesWithAuditAction + [Browsable(false)] + public bool AlreadyFetchedRolesWithAuditAction + { + get { return _alreadyFetchedRolesWithAuditAction;} + set + { + if(_alreadyFetchedRolesWithAuditAction && !value && (_rolesWithAuditAction != null)) + { + _rolesWithAuditAction.Clear(); + } + _alreadyFetchedRolesWithAuditAction = value; + } + } + + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.AuditActionEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/AuditDataCoreEntityBase.cs b/DAL/EntityBaseClasses/AuditDataCoreEntityBase.cs new file mode 100644 index 0000000..071ece5 --- /dev/null +++ b/DAL/EntityBaseClasses/AuditDataCoreEntityBase.cs @@ -0,0 +1,1165 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'AuditDataCore'.

+ /// + ///
+ [Serializable] + public abstract partial class AuditDataCoreEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private AuditActionEntity _auditAction; + private bool _alwaysFetchAuditAction, _alreadyFetchedAuditAction, _auditActionReturnsNewIfNotFound; + private UserEntity _userAudited; + private bool _alwaysFetchUserAudited, _alreadyFetchedUserAudited, _userAuditedReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name AuditAction + public static readonly string AuditAction = "AuditAction"; + /// Member name UserAudited + public static readonly string UserAudited = "UserAudited"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static AuditDataCoreEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public AuditDataCoreEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + public AuditDataCoreEntityBase(System.Int32 auditDataID) + { + InitClassFetch(auditDataID, null, null); + } + + /// CTor + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AuditDataCoreEntityBase(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(auditDataID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// The custom validator object for this AuditDataCoreEntity + public AuditDataCoreEntityBase(System.Int32 auditDataID, IValidator validator) + { + InitClassFetch(auditDataID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected AuditDataCoreEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _auditAction = (AuditActionEntity)info.GetValue("_auditAction", typeof(AuditActionEntity)); + if(_auditAction!=null) + { + _auditAction.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _auditActionReturnsNewIfNotFound = info.GetBoolean("_auditActionReturnsNewIfNotFound"); + _alwaysFetchAuditAction = info.GetBoolean("_alwaysFetchAuditAction"); + _alreadyFetchedAuditAction = info.GetBoolean("_alreadyFetchedAuditAction"); + _userAudited = (UserEntity)info.GetValue("_userAudited", typeof(UserEntity)); + if(_userAudited!=null) + { + _userAudited.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _userAuditedReturnsNewIfNotFound = info.GetBoolean("_userAuditedReturnsNewIfNotFound"); + _alwaysFetchUserAudited = info.GetBoolean("_alwaysFetchUserAudited"); + _alreadyFetchedUserAudited = info.GetBoolean("_alreadyFetchedUserAudited"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((AuditDataCoreFieldIndex)fieldIndex) + { + case AuditDataCoreFieldIndex.AuditActionID: + DesetupSyncAuditAction(true, false); + _alreadyFetchedAuditAction = false; + break; + case AuditDataCoreFieldIndex.UserID: + DesetupSyncUserAudited(true, false); + _alreadyFetchedUserAudited = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedAuditAction = (_auditAction != null); + _alreadyFetchedUserAudited = (_userAudited != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return AuditDataCoreEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "AuditAction": + toReturn.Add(AuditDataCoreEntity.Relations.AuditActionEntityUsingAuditActionID); + break; + case "UserAudited": + toReturn.Add(AuditDataCoreEntity.Relations.UserEntityUsingUserID); + break; + + + + default: + + break; + } + return toReturn; + } + + /// Gets the inheritance info for this entity, if applicable (it's then overriden) or null if not. + /// InheritanceInfo object if this entity is in a hierarchy of type TargetPerEntity, or null otherwise + [EditorBrowsable(EditorBrowsableState.Never)] + public override IInheritanceInfo GetInheritanceInfo() + { + return InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataCoreEntity", false); + } + + /// Gets a predicateexpression which filters on this entity + /// ready to use predicateexpression + /// Only useful in entity fetches. + public static IPredicateExpression GetEntityTypeFilter() + { + return InheritanceInfoProviderSingleton.GetInstance().GetEntityTypeFilter("AuditDataCoreEntity", false); + } + + /// Gets a predicateexpression which filters on this entity + /// Flag to produce a NOT filter, (true), or a normal filter (false). + /// ready to use predicateexpression + /// Only useful in entity fetches. + public static IPredicateExpression GetEntityTypeFilter(bool negate) + { + return InheritanceInfoProviderSingleton.GetInstance().GetEntityTypeFilter("AuditDataCoreEntity", negate); + } + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_auditAction", (!this.MarkedForDeletion?_auditAction:null)); + info.AddValue("_auditActionReturnsNewIfNotFound", _auditActionReturnsNewIfNotFound); + info.AddValue("_alwaysFetchAuditAction", _alwaysFetchAuditAction); + info.AddValue("_alreadyFetchedAuditAction", _alreadyFetchedAuditAction); + info.AddValue("_userAudited", (!this.MarkedForDeletion?_userAudited:null)); + info.AddValue("_userAuditedReturnsNewIfNotFound", _userAuditedReturnsNewIfNotFound); + info.AddValue("_alwaysFetchUserAudited", _alwaysFetchUserAudited); + info.AddValue("_alreadyFetchedUserAudited", _alreadyFetchedUserAudited); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "AuditAction": + _alreadyFetchedAuditAction = true; + this.AuditAction = (AuditActionEntity)entity; + break; + case "UserAudited": + _alreadyFetchedUserAudited = true; + this.UserAudited = (UserEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "AuditAction": + SetupSyncAuditAction(relatedEntity); + break; + case "UserAudited": + SetupSyncUserAudited(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "AuditAction": + DesetupSyncAuditAction(false, true); + break; + case "UserAudited": + DesetupSyncUserAudited(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_auditAction!=null) + { + toReturn.Add(_auditAction); + } + if(_userAudited!=null) + { + toReturn.Add(_userAudited); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + /// Fetches the contents of this entity from the persistent storage using the primary key specified in a polymorphic way, so the entity returned + /// could be of a subtype of the current entity or the current entity. + /// transaction to use during fetch + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// Context to use for fetch + /// Fetched entity of the type of this entity or a subtype, or an empty entity of that type if not found. + /// Creates a new instance, doesn't fill this entity instance + public static AuditDataCoreEntity FetchPolymorphic(ITransaction transactionToUse, System.Int32 auditDataID, Context contextToUse) + { + return FetchPolymorphic(transactionToUse, auditDataID, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key specified in a polymorphic way, so the entity returned + /// could be of a subtype of the current entity or the current entity. + /// transaction to use during fetch + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// Context to use for fetch + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// Fetched entity of the type of this entity or a subtype, or an empty entity of that type if not found. + /// Creates a new instance, doesn't fill this entity instance + public static AuditDataCoreEntity FetchPolymorphic(ITransaction transactionToUse, System.Int32 auditDataID, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + AuditDataCoreDAO dao = new AuditDataCoreDAO(); + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataCoreEntity); + fields[(int)AuditDataCoreFieldIndex.AuditDataID].ForcedCurrentValueWrite(auditDataID); + return (AuditDataCoreEntity)dao.FetchExistingPolymorphic(transactionToUse, fields, contextToUse, excludedIncludedFields); + } + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditDataID) + { + return FetchUsingPK(auditDataID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(auditDataID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(auditDataID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(auditDataID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.AuditDataID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(AuditDataCoreFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(AuditDataCoreFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + /// Determines whether this entity is a subType of the entity represented by the passed in enum value, which represents a value in the SD.HnD.DAL.EntityType enum + /// Type of entity. + /// true if the passed in type is a supertype of this entity, otherwise false + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool CheckIfIsSubTypeOf(int typeOfEntity) + { + return InheritanceInfoProviderSingleton.GetInstance().CheckIfIsSubTypeOf("AuditDataCoreEntity", ((SD.HnD.DAL.EntityType)typeOfEntity).ToString()); + } + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new AuditDataCoreRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'AuditActionEntity', using a relation of type 'n:1' + /// A fetched entity of type 'AuditActionEntity' which is related to this entity. + public AuditActionEntity GetSingleAuditAction() + { + return GetSingleAuditAction(false); + } + + /// Retrieves the related entity of type 'AuditActionEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'AuditActionEntity' which is related to this entity. + public virtual AuditActionEntity GetSingleAuditAction(bool forceFetch) + { + if( ( !_alreadyFetchedAuditAction || forceFetch || _alwaysFetchAuditAction) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(AuditDataCoreEntity.Relations.AuditActionEntityUsingAuditActionID); + + AuditActionEntity newEntity = new AuditActionEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.AuditActionID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (AuditActionEntity)base.ActiveContext.Get(newEntity); + } + this.AuditAction = newEntity; + } + else + { + if(_auditActionReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_auditAction == null))) + { + this.AuditAction = newEntity; + } + } + else + { + this.AuditAction = null; + } + } + _alreadyFetchedAuditAction = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _auditAction; + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSingleUserAudited() + { + return GetSingleUserAudited(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSingleUserAudited(bool forceFetch) + { + if( ( !_alreadyFetchedUserAudited || forceFetch || _alwaysFetchUserAudited) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(AuditDataCoreEntity.Relations.UserEntityUsingUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.UserID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.UserAudited = newEntity; + } + else + { + if(_userAuditedReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_userAudited == null))) + { + this.UserAudited = newEntity; + } + } + else + { + this.UserAudited = null; + } + } + _alreadyFetchedUserAudited = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _userAudited; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + AuditDataCoreDAO dao = (AuditDataCoreDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_auditAction!=null) + { + _auditAction.ActiveContext = base.ActiveContext; + } + if(_userAudited!=null) + { + _userAudited.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + AuditDataCoreDAO dao = (AuditDataCoreDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + AuditDataCoreDAO dao = (AuditDataCoreDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataCoreEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("AuditAction", _auditAction); + toReturn.Add("UserAudited", _userAudited); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// The validator object for this AuditDataCoreEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 auditDataID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(auditDataID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _auditAction = null; + _auditActionReturnsNewIfNotFound = true; + _alwaysFetchAuditAction = false; + _alreadyFetchedAuditAction = false; + _userAudited = null; + _userAuditedReturnsNewIfNotFound = true; + _alwaysFetchUserAudited = false; + _alreadyFetchedUserAudited = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AuditDataID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AuditActionID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("UserID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AuditedOn", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _auditAction + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncAuditAction(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _auditAction, new PropertyChangedEventHandler( OnAuditActionPropertyChanged ), "AuditAction", AuditDataCoreEntity.Relations.AuditActionEntityUsingAuditActionID, true, signalRelatedEntity, "AuditDataCore", resetFKFields, new int[] { (int)AuditDataCoreFieldIndex.AuditActionID } ); + _auditAction = null; + } + + /// setups the sync logic for member _auditAction + /// Instance to set as the related entity of type entityType + private void SetupSyncAuditAction(IEntity relatedEntity) + { + if(_auditAction!=relatedEntity) + { + DesetupSyncAuditAction(true, true); + _auditAction = (AuditActionEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _auditAction, new PropertyChangedEventHandler( OnAuditActionPropertyChanged ), "AuditAction", AuditDataCoreEntity.Relations.AuditActionEntityUsingAuditActionID, true, ref _alreadyFetchedAuditAction, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnAuditActionPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _userAudited + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncUserAudited(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _userAudited, new PropertyChangedEventHandler( OnUserAuditedPropertyChanged ), "UserAudited", AuditDataCoreEntity.Relations.UserEntityUsingUserID, true, signalRelatedEntity, "LoggedAudits", resetFKFields, new int[] { (int)AuditDataCoreFieldIndex.UserID } ); + _userAudited = null; + } + + /// setups the sync logic for member _userAudited + /// Instance to set as the related entity of type entityType + private void SetupSyncUserAudited(IEntity relatedEntity) + { + if(_userAudited!=relatedEntity) + { + DesetupSyncUserAudited(true, true); + _userAudited = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _userAudited, new PropertyChangedEventHandler( OnUserAuditedPropertyChanged ), "UserAudited", AuditDataCoreEntity.Relations.UserEntityUsingUserID, true, ref _alreadyFetchedUserAudited, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnUserAuditedPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)AuditDataCoreFieldIndex.AuditDataID].ForcedCurrentValueWrite(auditDataID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAuditDataCoreDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new AuditDataCoreEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static AuditDataCoreRelations Relations + { + get { return new AuditDataCoreRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'AuditAction' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathAuditAction + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.AuditActionCollection(), + (IEntityRelation)GetRelationsForField("AuditAction")[0], (int)SD.HnD.DAL.EntityType.AuditDataCoreEntity, (int)SD.HnD.DAL.EntityType.AuditActionEntity, 0, null, null, null, "AuditAction", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUserAudited + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("UserAudited")[0], (int)SD.HnD.DAL.EntityType.AuditDataCoreEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "UserAudited", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "AuditDataCoreEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return AuditDataCoreEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return AuditDataCoreEntity.FieldsCustomProperties;} + } + + /// The AuditDataID property of the Entity AuditDataCore

+ ///
+ /// Mapped on table field: "AuditDataCore"."AuditDataID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 AuditDataID + { + get { return (System.Int32)GetValue((int)AuditDataCoreFieldIndex.AuditDataID, true); } + set { SetValue((int)AuditDataCoreFieldIndex.AuditDataID, value, true); } + } + /// The AuditActionID property of the Entity AuditDataCore

+ ///
+ /// Mapped on table field: "AuditDataCore"."AuditActionID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 AuditActionID + { + get { return (System.Int32)GetValue((int)AuditDataCoreFieldIndex.AuditActionID, true); } + set { SetValue((int)AuditDataCoreFieldIndex.AuditActionID, value, true); } + } + /// The UserID property of the Entity AuditDataCore

+ ///
+ /// Mapped on table field: "AuditDataCore"."UserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 UserID + { + get { return (System.Int32)GetValue((int)AuditDataCoreFieldIndex.UserID, true); } + set { SetValue((int)AuditDataCoreFieldIndex.UserID, value, true); } + } + /// The AuditedOn property of the Entity AuditDataCore

+ ///
+ /// Mapped on table field: "AuditDataCore"."AuditedOn"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.DateTime AuditedOn + { + get { return (System.DateTime)GetValue((int)AuditDataCoreFieldIndex.AuditedOn, true); } + set { SetValue((int)AuditDataCoreFieldIndex.AuditedOn, value, true); } + } + + + + /// Gets / sets related entity of type 'AuditActionEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleAuditAction()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual AuditActionEntity AuditAction + { + get { return GetSingleAuditAction(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncAuditAction(value); + } + else + { + if(value==null) + { + if(_auditAction != null) + { + _auditAction.UnsetRelatedEntity(this, "AuditDataCore"); + } + } + else + { + if(_auditAction!=value) + { + ((IEntity)value).SetRelatedEntity(this, "AuditDataCore"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for AuditAction. When set to true, AuditAction is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time AuditAction is accessed. You can always execute + /// a forced fetch by calling GetSingleAuditAction(true). + [Browsable(false)] + public bool AlwaysFetchAuditAction + { + get { return _alwaysFetchAuditAction; } + set { _alwaysFetchAuditAction = value; } + } + + /// Gets / Sets the lazy loading flag if the property AuditAction already has been fetched. Setting this property to false when AuditAction has been fetched + /// will set AuditAction to null as well. Setting this property to true while AuditAction hasn't been fetched disables lazy loading for AuditAction + [Browsable(false)] + public bool AlreadyFetchedAuditAction + { + get { return _alreadyFetchedAuditAction;} + set + { + if(_alreadyFetchedAuditAction && !value) + { + this.AuditAction = null; + } + _alreadyFetchedAuditAction = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property AuditAction is not found + /// in the database. When set to true, AuditAction will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool AuditActionReturnsNewIfNotFound + { + get { return _auditActionReturnsNewIfNotFound; } + set { _auditActionReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleUserAudited()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity UserAudited + { + get { return GetSingleUserAudited(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncUserAudited(value); + } + else + { + if(value==null) + { + if(_userAudited != null) + { + _userAudited.UnsetRelatedEntity(this, "LoggedAudits"); + } + } + else + { + if(_userAudited!=value) + { + ((IEntity)value).SetRelatedEntity(this, "LoggedAudits"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for UserAudited. When set to true, UserAudited is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time UserAudited is accessed. You can always execute + /// a forced fetch by calling GetSingleUserAudited(true). + [Browsable(false)] + public bool AlwaysFetchUserAudited + { + get { return _alwaysFetchUserAudited; } + set { _alwaysFetchUserAudited = value; } + } + + /// Gets / Sets the lazy loading flag if the property UserAudited already has been fetched. Setting this property to false when UserAudited has been fetched + /// will set UserAudited to null as well. Setting this property to true while UserAudited hasn't been fetched disables lazy loading for UserAudited + [Browsable(false)] + public bool AlreadyFetchedUserAudited + { + get { return _alreadyFetchedUserAudited;} + set + { + if(_alreadyFetchedUserAudited && !value) + { + this.UserAudited = null; + } + _alreadyFetchedUserAudited = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property UserAudited is not found + /// in the database. When set to true, UserAudited will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool UserAuditedReturnsNewIfNotFound + { + get { return _userAuditedReturnsNewIfNotFound; } + set { _userAuditedReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.TargetPerEntity;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.AuditDataCoreEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/AuditDataMessageRelatedEntityBase.cs b/DAL/EntityBaseClasses/AuditDataMessageRelatedEntityBase.cs new file mode 100644 index 0000000..a1b3521 --- /dev/null +++ b/DAL/EntityBaseClasses/AuditDataMessageRelatedEntityBase.cs @@ -0,0 +1,847 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'AuditDataMessageRelated'.

+ /// + ///
+ [Serializable] + public partial class AuditDataMessageRelatedEntityBase : AuditDataCoreEntity, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private MessageEntity _message; + private bool _alwaysFetchMessage, _alreadyFetchedMessage, _messageReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static new class MemberNames + { + /// Member name AuditAction + public static readonly string AuditAction = "AuditAction"; + /// Member name Message + public static readonly string Message = "Message"; + /// Member name UserAudited + public static readonly string UserAudited = "UserAudited"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static AuditDataMessageRelatedEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public AuditDataMessageRelatedEntityBase() + { + + } + + + /// CTor + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + public AuditDataMessageRelatedEntityBase(System.Int32 auditDataID):base(auditDataID) + { + + } + + /// CTor + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AuditDataMessageRelatedEntityBase(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse):base(auditDataID, prefetchPathToUse) + { + + } + + /// CTor + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + /// The custom validator object for this AuditDataMessageRelatedEntity + public AuditDataMessageRelatedEntityBase(System.Int32 auditDataID, IValidator validator):base(auditDataID, validator) + { + + } + + + /// Protected CTor for deserialization + /// + /// + protected AuditDataMessageRelatedEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _message = (MessageEntity)info.GetValue("_message", typeof(MessageEntity)); + if(_message!=null) + { + _message.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _messageReturnsNewIfNotFound = info.GetBoolean("_messageReturnsNewIfNotFound"); + _alwaysFetchMessage = info.GetBoolean("_alwaysFetchMessage"); + _alreadyFetchedMessage = info.GetBoolean("_alreadyFetchedMessage"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((AuditDataMessageRelatedFieldIndex)fieldIndex) + { + case AuditDataMessageRelatedFieldIndex.MessageID: + DesetupSyncMessage(true, false); + _alreadyFetchedMessage = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedMessage = (_message != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return AuditDataMessageRelatedEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static new RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "Message": + toReturn.Add(AuditDataMessageRelatedEntity.Relations.MessageEntityUsingMessageID); + break; + + + + default: + toReturn = AuditDataCoreEntity.GetRelationsForField(fieldName); + break; + } + return toReturn; + } + + /// Gets the inheritance info for this entity, if applicable (it's then overriden) or null if not. + /// InheritanceInfo object if this entity is in a hierarchy of type TargetPerEntity, or null otherwise + [EditorBrowsable(EditorBrowsableState.Never)] + public override IInheritanceInfo GetInheritanceInfo() + { + return InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataMessageRelatedEntity", false); + } + + /// Gets a predicateexpression which filters on this entity + /// ready to use predicateexpression + /// Only useful in entity fetches. + public new static IPredicateExpression GetEntityTypeFilter() + { + return InheritanceInfoProviderSingleton.GetInstance().GetEntityTypeFilter("AuditDataMessageRelatedEntity", false); + } + + /// Gets a predicateexpression which filters on this entity + /// Flag to produce a NOT filter, (true), or a normal filter (false). + /// ready to use predicateexpression + /// Only useful in entity fetches. + public new static IPredicateExpression GetEntityTypeFilter(bool negate) + { + return InheritanceInfoProviderSingleton.GetInstance().GetEntityTypeFilter("AuditDataMessageRelatedEntity", negate); + } + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_message", (!this.MarkedForDeletion?_message:null)); + info.AddValue("_messageReturnsNewIfNotFound", _messageReturnsNewIfNotFound); + info.AddValue("_alwaysFetchMessage", _alwaysFetchMessage); + info.AddValue("_alreadyFetchedMessage", _alreadyFetchedMessage); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "Message": + _alreadyFetchedMessage = true; + this.Message = (MessageEntity)entity; + break; + + + + default: + base.SetRelatedEntityProperty(propertyName, entity); + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "Message": + SetupSyncMessage(relatedEntity); + break; + + + default: + base.SetRelatedEntity(relatedEntity, fieldName); + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "Message": + DesetupSyncMessage(false, true); + break; + + + default: + base.UnsetRelatedEntity(relatedEntity, fieldName, signalRelatedEntityManyToOne); + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + toReturn.AddRange(base.GetDependingRelatedEntities()); + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_message!=null) + { + toReturn.Add(_message); + } + + toReturn.AddRange(base.GetDependentRelatedEntities()); + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + toReturn.AddRange(base.GetMemberEntityCollections()); + return toReturn; + } + + + + /// Fetches the contents of this entity from the persistent storage using the primary key specified in a polymorphic way, so the entity returned + /// could be of a subtype of the current entity or the current entity. + /// transaction to use during fetch + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + /// Context to use for fetch + /// Fetched entity of the type of this entity or a subtype, or an empty entity of that type if not found. + /// Creates a new instance, doesn't fill this entity instance + public static new AuditDataMessageRelatedEntity FetchPolymorphic(ITransaction transactionToUse, System.Int32 auditDataID, Context contextToUse) + { + return FetchPolymorphic(transactionToUse, auditDataID, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key specified in a polymorphic way, so the entity returned + /// could be of a subtype of the current entity or the current entity. + /// transaction to use during fetch + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + /// Context to use for fetch + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// Fetched entity of the type of this entity or a subtype, or an empty entity of that type if not found. + /// Creates a new instance, doesn't fill this entity instance + public static new AuditDataMessageRelatedEntity FetchPolymorphic(ITransaction transactionToUse, System.Int32 auditDataID, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + AuditDataMessageRelatedDAO dao = new AuditDataMessageRelatedDAO(); + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity); + fields[(int)AuditDataMessageRelatedFieldIndex.AuditDataID].ForcedCurrentValueWrite(auditDataID); + return (AuditDataMessageRelatedEntity)dao.FetchExistingPolymorphic(transactionToUse, fields, contextToUse, excludedIncludedFields); + } + + + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(AuditDataMessageRelatedFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(AuditDataMessageRelatedFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + /// Determines whether this entity is a subType of the entity represented by the passed in enum value, which represents a value in the SD.HnD.DAL.EntityType enum + /// Type of entity. + /// true if the passed in type is a supertype of this entity, otherwise false + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool CheckIfIsSubTypeOf(int typeOfEntity) + { + return InheritanceInfoProviderSingleton.GetInstance().CheckIfIsSubTypeOf("AuditDataMessageRelatedEntity", ((SD.HnD.DAL.EntityType)typeOfEntity).ToString()); + } + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new AuditDataMessageRelatedRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'MessageEntity', using a relation of type 'n:1' + /// A fetched entity of type 'MessageEntity' which is related to this entity. + public MessageEntity GetSingleMessage() + { + return GetSingleMessage(false); + } + + /// Retrieves the related entity of type 'MessageEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'MessageEntity' which is related to this entity. + public virtual MessageEntity GetSingleMessage(bool forceFetch) + { + if( ( !_alreadyFetchedMessage || forceFetch || _alwaysFetchMessage) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(AuditDataMessageRelatedEntity.Relations.MessageEntityUsingMessageID); + + MessageEntity newEntity = new MessageEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.MessageID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (MessageEntity)base.ActiveContext.Get(newEntity); + } + this.Message = newEntity; + } + else + { + if(_messageReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_message == null))) + { + this.Message = newEntity; + } + } + else + { + this.Message = null; + } + } + _alreadyFetchedMessage = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _message; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + AuditDataMessageRelatedDAO dao = (AuditDataMessageRelatedDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_message!=null) + { + _message.ActiveContext = base.ActiveContext; + } + + base.AddInternalsToContext(); + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + AuditDataMessageRelatedDAO dao = (AuditDataMessageRelatedDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + AuditDataMessageRelatedDAO dao = (AuditDataMessageRelatedDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected override void InitClassEmpty(IValidator validatorToUse) + { + + base.InitClassEmpty(validatorToUse); + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected override IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = base.GetRelatedData(); + toReturn.Add("Message", _message); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + /// The validator object for this AuditDataMessageRelatedEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected override void InitClassFetch(System.Int32 auditDataID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + + InitClassMembers(); + base.InitClassFetch(auditDataID, validator, prefetchPathToUse); + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _message = null; + _messageReturnsNewIfNotFound = true; + _alwaysFetchMessage = false; + _alreadyFetchedMessage = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AuditDataID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MessageID", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _message + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncMessage(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _message, new PropertyChangedEventHandler( OnMessagePropertyChanged ), "Message", AuditDataMessageRelatedEntity.Relations.MessageEntityUsingMessageID, true, signalRelatedEntity, "AuditDataMessageRelated", resetFKFields, new int[] { (int)AuditDataMessageRelatedFieldIndex.MessageID } ); + _message = null; + } + + /// setups the sync logic for member _message + /// Instance to set as the related entity of type entityType + private void SetupSyncMessage(IEntity relatedEntity) + { + if(_message!=relatedEntity) + { + DesetupSyncMessage(true, true); + _message = (MessageEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _message, new PropertyChangedEventHandler( OnMessagePropertyChanged ), "Message", AuditDataMessageRelatedEntity.Relations.MessageEntityUsingMessageID, true, ref _alreadyFetchedMessage, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnMessagePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAuditDataMessageRelatedDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new AuditDataMessageRelatedEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public new static AuditDataMessageRelatedRelations Relations + { + get { return new AuditDataMessageRelatedRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public new static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Message' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathMessage + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.MessageCollection(), + (IEntityRelation)GetRelationsForField("Message")[0], (int)SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity, (int)SD.HnD.DAL.EntityType.MessageEntity, 0, null, null, null, "Message", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "AuditDataMessageRelatedEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return AuditDataMessageRelatedEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public new static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return AuditDataMessageRelatedEntity.FieldsCustomProperties;} + } + + /// The AuditDataID property of the Entity AuditDataMessageRelated

+ ///
+ /// Mapped on table field: "AuditDataMessageRelated"."AuditDataID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public override System.Int32 AuditDataID + { + get { return (System.Int32)GetValue((int)AuditDataMessageRelatedFieldIndex.AuditDataID, true); } + set { SetValue((int)AuditDataMessageRelatedFieldIndex.AuditDataID, value, true); } + } + /// The MessageID property of the Entity AuditDataMessageRelated

+ ///
+ /// Mapped on table field: "AuditDataMessageRelated"."MessageID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 MessageID + { + get { return (System.Int32)GetValue((int)AuditDataMessageRelatedFieldIndex.MessageID, true); } + set { SetValue((int)AuditDataMessageRelatedFieldIndex.MessageID, value, true); } + } + + + + /// Gets / sets related entity of type 'MessageEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleMessage()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual MessageEntity Message + { + get { return GetSingleMessage(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncMessage(value); + } + else + { + if(value==null) + { + if(_message != null) + { + _message.UnsetRelatedEntity(this, "AuditDataMessageRelated"); + } + } + else + { + if(_message!=value) + { + ((IEntity)value).SetRelatedEntity(this, "AuditDataMessageRelated"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Message. When set to true, Message is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Message is accessed. You can always execute + /// a forced fetch by calling GetSingleMessage(true). + [Browsable(false)] + public bool AlwaysFetchMessage + { + get { return _alwaysFetchMessage; } + set { _alwaysFetchMessage = value; } + } + + /// Gets / Sets the lazy loading flag if the property Message already has been fetched. Setting this property to false when Message has been fetched + /// will set Message to null as well. Setting this property to true while Message hasn't been fetched disables lazy loading for Message + [Browsable(false)] + public bool AlreadyFetchedMessage + { + get { return _alreadyFetchedMessage;} + set + { + if(_alreadyFetchedMessage && !value) + { + this.Message = null; + } + _alreadyFetchedMessage = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Message is not found + /// in the database. When set to true, Message will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool MessageReturnsNewIfNotFound + { + get { return _messageReturnsNewIfNotFound; } + set { _messageReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return true;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.TargetPerEntity;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/AuditDataThreadRelatedEntityBase.cs b/DAL/EntityBaseClasses/AuditDataThreadRelatedEntityBase.cs new file mode 100644 index 0000000..7c19f4a --- /dev/null +++ b/DAL/EntityBaseClasses/AuditDataThreadRelatedEntityBase.cs @@ -0,0 +1,847 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'AuditDataThreadRelated'.

+ /// + ///
+ [Serializable] + public partial class AuditDataThreadRelatedEntityBase : AuditDataCoreEntity, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private ThreadEntity _thread; + private bool _alwaysFetchThread, _alreadyFetchedThread, _threadReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static new class MemberNames + { + /// Member name AuditAction + public static readonly string AuditAction = "AuditAction"; + /// Member name Thread + public static readonly string Thread = "Thread"; + /// Member name UserAudited + public static readonly string UserAudited = "UserAudited"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static AuditDataThreadRelatedEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public AuditDataThreadRelatedEntityBase() + { + + } + + + /// CTor + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + public AuditDataThreadRelatedEntityBase(System.Int32 auditDataID):base(auditDataID) + { + + } + + /// CTor + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AuditDataThreadRelatedEntityBase(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse):base(auditDataID, prefetchPathToUse) + { + + } + + /// CTor + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + /// The custom validator object for this AuditDataThreadRelatedEntity + public AuditDataThreadRelatedEntityBase(System.Int32 auditDataID, IValidator validator):base(auditDataID, validator) + { + + } + + + /// Protected CTor for deserialization + /// + /// + protected AuditDataThreadRelatedEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _thread = (ThreadEntity)info.GetValue("_thread", typeof(ThreadEntity)); + if(_thread!=null) + { + _thread.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _threadReturnsNewIfNotFound = info.GetBoolean("_threadReturnsNewIfNotFound"); + _alwaysFetchThread = info.GetBoolean("_alwaysFetchThread"); + _alreadyFetchedThread = info.GetBoolean("_alreadyFetchedThread"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((AuditDataThreadRelatedFieldIndex)fieldIndex) + { + case AuditDataThreadRelatedFieldIndex.ThreadID: + DesetupSyncThread(true, false); + _alreadyFetchedThread = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedThread = (_thread != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return AuditDataThreadRelatedEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static new RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "Thread": + toReturn.Add(AuditDataThreadRelatedEntity.Relations.ThreadEntityUsingThreadID); + break; + + + + default: + toReturn = AuditDataCoreEntity.GetRelationsForField(fieldName); + break; + } + return toReturn; + } + + /// Gets the inheritance info for this entity, if applicable (it's then overriden) or null if not. + /// InheritanceInfo object if this entity is in a hierarchy of type TargetPerEntity, or null otherwise + [EditorBrowsable(EditorBrowsableState.Never)] + public override IInheritanceInfo GetInheritanceInfo() + { + return InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataThreadRelatedEntity", false); + } + + /// Gets a predicateexpression which filters on this entity + /// ready to use predicateexpression + /// Only useful in entity fetches. + public new static IPredicateExpression GetEntityTypeFilter() + { + return InheritanceInfoProviderSingleton.GetInstance().GetEntityTypeFilter("AuditDataThreadRelatedEntity", false); + } + + /// Gets a predicateexpression which filters on this entity + /// Flag to produce a NOT filter, (true), or a normal filter (false). + /// ready to use predicateexpression + /// Only useful in entity fetches. + public new static IPredicateExpression GetEntityTypeFilter(bool negate) + { + return InheritanceInfoProviderSingleton.GetInstance().GetEntityTypeFilter("AuditDataThreadRelatedEntity", negate); + } + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_thread", (!this.MarkedForDeletion?_thread:null)); + info.AddValue("_threadReturnsNewIfNotFound", _threadReturnsNewIfNotFound); + info.AddValue("_alwaysFetchThread", _alwaysFetchThread); + info.AddValue("_alreadyFetchedThread", _alreadyFetchedThread); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "Thread": + _alreadyFetchedThread = true; + this.Thread = (ThreadEntity)entity; + break; + + + + default: + base.SetRelatedEntityProperty(propertyName, entity); + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "Thread": + SetupSyncThread(relatedEntity); + break; + + + default: + base.SetRelatedEntity(relatedEntity, fieldName); + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "Thread": + DesetupSyncThread(false, true); + break; + + + default: + base.UnsetRelatedEntity(relatedEntity, fieldName, signalRelatedEntityManyToOne); + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + toReturn.AddRange(base.GetDependingRelatedEntities()); + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_thread!=null) + { + toReturn.Add(_thread); + } + + toReturn.AddRange(base.GetDependentRelatedEntities()); + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + toReturn.AddRange(base.GetMemberEntityCollections()); + return toReturn; + } + + + + /// Fetches the contents of this entity from the persistent storage using the primary key specified in a polymorphic way, so the entity returned + /// could be of a subtype of the current entity or the current entity. + /// transaction to use during fetch + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + /// Context to use for fetch + /// Fetched entity of the type of this entity or a subtype, or an empty entity of that type if not found. + /// Creates a new instance, doesn't fill this entity instance + public static new AuditDataThreadRelatedEntity FetchPolymorphic(ITransaction transactionToUse, System.Int32 auditDataID, Context contextToUse) + { + return FetchPolymorphic(transactionToUse, auditDataID, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key specified in a polymorphic way, so the entity returned + /// could be of a subtype of the current entity or the current entity. + /// transaction to use during fetch + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + /// Context to use for fetch + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// Fetched entity of the type of this entity or a subtype, or an empty entity of that type if not found. + /// Creates a new instance, doesn't fill this entity instance + public static new AuditDataThreadRelatedEntity FetchPolymorphic(ITransaction transactionToUse, System.Int32 auditDataID, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + AuditDataThreadRelatedDAO dao = new AuditDataThreadRelatedDAO(); + IEntityFields fields = EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity); + fields[(int)AuditDataThreadRelatedFieldIndex.AuditDataID].ForcedCurrentValueWrite(auditDataID); + return (AuditDataThreadRelatedEntity)dao.FetchExistingPolymorphic(transactionToUse, fields, contextToUse, excludedIncludedFields); + } + + + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(AuditDataThreadRelatedFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(AuditDataThreadRelatedFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + /// Determines whether this entity is a subType of the entity represented by the passed in enum value, which represents a value in the SD.HnD.DAL.EntityType enum + /// Type of entity. + /// true if the passed in type is a supertype of this entity, otherwise false + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool CheckIfIsSubTypeOf(int typeOfEntity) + { + return InheritanceInfoProviderSingleton.GetInstance().CheckIfIsSubTypeOf("AuditDataThreadRelatedEntity", ((SD.HnD.DAL.EntityType)typeOfEntity).ToString()); + } + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new AuditDataThreadRelatedRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type 'n:1' + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public ThreadEntity GetSingleThread() + { + return GetSingleThread(false); + } + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public virtual ThreadEntity GetSingleThread(bool forceFetch) + { + if( ( !_alreadyFetchedThread || forceFetch || _alwaysFetchThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(AuditDataThreadRelatedEntity.Relations.ThreadEntityUsingThreadID); + + ThreadEntity newEntity = new ThreadEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ThreadID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (ThreadEntity)base.ActiveContext.Get(newEntity); + } + this.Thread = newEntity; + } + else + { + if(_threadReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_thread == null))) + { + this.Thread = newEntity; + } + } + else + { + this.Thread = null; + } + } + _alreadyFetchedThread = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _thread; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + AuditDataThreadRelatedDAO dao = (AuditDataThreadRelatedDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_thread!=null) + { + _thread.ActiveContext = base.ActiveContext; + } + + base.AddInternalsToContext(); + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + AuditDataThreadRelatedDAO dao = (AuditDataThreadRelatedDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + AuditDataThreadRelatedDAO dao = (AuditDataThreadRelatedDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected override void InitClassEmpty(IValidator validatorToUse) + { + + base.InitClassEmpty(validatorToUse); + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected override IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = base.GetRelatedData(); + toReturn.Add("Thread", _thread); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + /// The validator object for this AuditDataThreadRelatedEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected override void InitClassFetch(System.Int32 auditDataID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + + InitClassMembers(); + base.InitClassFetch(auditDataID, validator, prefetchPathToUse); + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _thread = null; + _threadReturnsNewIfNotFound = true; + _alwaysFetchThread = false; + _alreadyFetchedThread = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AuditDataID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _thread + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncThread(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", AuditDataThreadRelatedEntity.Relations.ThreadEntityUsingThreadID, true, signalRelatedEntity, "AuditDataThreadRelated", resetFKFields, new int[] { (int)AuditDataThreadRelatedFieldIndex.ThreadID } ); + _thread = null; + } + + /// setups the sync logic for member _thread + /// Instance to set as the related entity of type entityType + private void SetupSyncThread(IEntity relatedEntity) + { + if(_thread!=relatedEntity) + { + DesetupSyncThread(true, true); + _thread = (ThreadEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", AuditDataThreadRelatedEntity.Relations.ThreadEntityUsingThreadID, true, ref _alreadyFetchedThread, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnThreadPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateAuditDataThreadRelatedDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new AuditDataThreadRelatedEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public new static AuditDataThreadRelatedRelations Relations + { + get { return new AuditDataThreadRelatedRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public new static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThread + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), + (IEntityRelation)GetRelationsForField("Thread")[0], (int)SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, null, "Thread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "AuditDataThreadRelatedEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return AuditDataThreadRelatedEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public new static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return AuditDataThreadRelatedEntity.FieldsCustomProperties;} + } + + /// The AuditDataID property of the Entity AuditDataThreadRelated

+ ///
+ /// Mapped on table field: "AuditDataThreadRelated"."AuditDataID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public override System.Int32 AuditDataID + { + get { return (System.Int32)GetValue((int)AuditDataThreadRelatedFieldIndex.AuditDataID, true); } + set { SetValue((int)AuditDataThreadRelatedFieldIndex.AuditDataID, value, true); } + } + /// The ThreadID property of the Entity AuditDataThreadRelated

+ ///
+ /// Mapped on table field: "AuditDataThreadRelated"."ThreadID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 ThreadID + { + get { return (System.Int32)GetValue((int)AuditDataThreadRelatedFieldIndex.ThreadID, true); } + set { SetValue((int)AuditDataThreadRelatedFieldIndex.ThreadID, value, true); } + } + + + + /// Gets / sets related entity of type 'ThreadEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ThreadEntity Thread + { + get { return GetSingleThread(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncThread(value); + } + else + { + if(value==null) + { + if(_thread != null) + { + _thread.UnsetRelatedEntity(this, "AuditDataThreadRelated"); + } + } + else + { + if(_thread!=value) + { + ((IEntity)value).SetRelatedEntity(this, "AuditDataThreadRelated"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Thread. When set to true, Thread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Thread is accessed. You can always execute + /// a forced fetch by calling GetSingleThread(true). + [Browsable(false)] + public bool AlwaysFetchThread + { + get { return _alwaysFetchThread; } + set { _alwaysFetchThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property Thread already has been fetched. Setting this property to false when Thread has been fetched + /// will set Thread to null as well. Setting this property to true while Thread hasn't been fetched disables lazy loading for Thread + [Browsable(false)] + public bool AlreadyFetchedThread + { + get { return _alreadyFetchedThread;} + set + { + if(_alreadyFetchedThread && !value) + { + this.Thread = null; + } + _alreadyFetchedThread = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Thread is not found + /// in the database. When set to true, Thread will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ThreadReturnsNewIfNotFound + { + get { return _threadReturnsNewIfNotFound; } + set { _threadReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return true;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.TargetPerEntity;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/BookmarkEntityBase.cs b/DAL/EntityBaseClasses/BookmarkEntityBase.cs new file mode 100644 index 0000000..53ede0a --- /dev/null +++ b/DAL/EntityBaseClasses/BookmarkEntityBase.cs @@ -0,0 +1,1089 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'Bookmark'.

+ /// + ///
+ [Serializable] + public abstract partial class BookmarkEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private ThreadEntity _thread; + private bool _alwaysFetchThread, _alreadyFetchedThread, _threadReturnsNewIfNotFound; + private UserEntity _user; + private bool _alwaysFetchUser, _alreadyFetchedUser, _userReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name Thread + public static readonly string Thread = "Thread"; + /// Member name User + public static readonly string User = "User"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static BookmarkEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public BookmarkEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + public BookmarkEntityBase(System.Int32 threadID, System.Int32 userID) + { + InitClassFetch(threadID, userID, null, null); + } + + /// CTor + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// the PrefetchPath which defines the graph of objects to fetch as well + public BookmarkEntityBase(System.Int32 threadID, System.Int32 userID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(threadID, userID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// The custom validator object for this BookmarkEntity + public BookmarkEntityBase(System.Int32 threadID, System.Int32 userID, IValidator validator) + { + InitClassFetch(threadID, userID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected BookmarkEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _thread = (ThreadEntity)info.GetValue("_thread", typeof(ThreadEntity)); + if(_thread!=null) + { + _thread.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _threadReturnsNewIfNotFound = info.GetBoolean("_threadReturnsNewIfNotFound"); + _alwaysFetchThread = info.GetBoolean("_alwaysFetchThread"); + _alreadyFetchedThread = info.GetBoolean("_alreadyFetchedThread"); + _user = (UserEntity)info.GetValue("_user", typeof(UserEntity)); + if(_user!=null) + { + _user.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _userReturnsNewIfNotFound = info.GetBoolean("_userReturnsNewIfNotFound"); + _alwaysFetchUser = info.GetBoolean("_alwaysFetchUser"); + _alreadyFetchedUser = info.GetBoolean("_alreadyFetchedUser"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((BookmarkFieldIndex)fieldIndex) + { + case BookmarkFieldIndex.ThreadID: + DesetupSyncThread(true, false); + _alreadyFetchedThread = false; + break; + case BookmarkFieldIndex.UserID: + DesetupSyncUser(true, false); + _alreadyFetchedUser = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedThread = (_thread != null); + _alreadyFetchedUser = (_user != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return BookmarkEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "Thread": + toReturn.Add(BookmarkEntity.Relations.ThreadEntityUsingThreadID); + break; + case "User": + toReturn.Add(BookmarkEntity.Relations.UserEntityUsingUserID); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_thread", (!this.MarkedForDeletion?_thread:null)); + info.AddValue("_threadReturnsNewIfNotFound", _threadReturnsNewIfNotFound); + info.AddValue("_alwaysFetchThread", _alwaysFetchThread); + info.AddValue("_alreadyFetchedThread", _alreadyFetchedThread); + info.AddValue("_user", (!this.MarkedForDeletion?_user:null)); + info.AddValue("_userReturnsNewIfNotFound", _userReturnsNewIfNotFound); + info.AddValue("_alwaysFetchUser", _alwaysFetchUser); + info.AddValue("_alreadyFetchedUser", _alreadyFetchedUser); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "Thread": + _alreadyFetchedThread = true; + this.Thread = (ThreadEntity)entity; + break; + case "User": + _alreadyFetchedUser = true; + this.User = (UserEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "Thread": + SetupSyncThread(relatedEntity); + break; + case "User": + SetupSyncUser(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "Thread": + DesetupSyncThread(false, true); + break; + case "User": + DesetupSyncUser(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_thread!=null) + { + toReturn.Add(_thread); + } + if(_user!=null) + { + toReturn.Add(_user); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 threadID, System.Int32 userID) + { + return FetchUsingPK(threadID, userID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 threadID, System.Int32 userID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(threadID, userID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 threadID, System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(threadID, userID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 threadID, System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(threadID, userID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.ThreadID, this.UserID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(BookmarkFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(BookmarkFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new BookmarkRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type 'n:1' + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public ThreadEntity GetSingleThread() + { + return GetSingleThread(false); + } + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public virtual ThreadEntity GetSingleThread(bool forceFetch) + { + if( ( !_alreadyFetchedThread || forceFetch || _alwaysFetchThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(BookmarkEntity.Relations.ThreadEntityUsingThreadID); + + ThreadEntity newEntity = new ThreadEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ThreadID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (ThreadEntity)base.ActiveContext.Get(newEntity); + } + this.Thread = newEntity; + } + else + { + if(_threadReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_thread == null))) + { + this.Thread = newEntity; + } + } + else + { + this.Thread = null; + } + } + _alreadyFetchedThread = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _thread; + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSingleUser() + { + return GetSingleUser(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSingleUser(bool forceFetch) + { + if( ( !_alreadyFetchedUser || forceFetch || _alwaysFetchUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(BookmarkEntity.Relations.UserEntityUsingUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.UserID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.User = newEntity; + } + else + { + if(_userReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_user == null))) + { + this.User = newEntity; + } + } + else + { + this.User = null; + } + } + _alreadyFetchedUser = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _user; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + BookmarkDAO dao = (BookmarkDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_thread!=null) + { + _thread.ActiveContext = base.ActiveContext; + } + if(_user!=null) + { + _user.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + BookmarkDAO dao = (BookmarkDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + BookmarkDAO dao = (BookmarkDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.BookmarkEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("Thread", _thread); + toReturn.Add("User", _user); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// The validator object for this BookmarkEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 threadID, System.Int32 userID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(threadID, userID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _thread = null; + _threadReturnsNewIfNotFound = true; + _alwaysFetchThread = false; + _alreadyFetchedThread = false; + _user = null; + _userReturnsNewIfNotFound = true; + _alwaysFetchUser = false; + _alreadyFetchedUser = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("UserID", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _thread + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncThread(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", BookmarkEntity.Relations.ThreadEntityUsingThreadID, true, signalRelatedEntity, "PresentInBookmarks", resetFKFields, new int[] { (int)BookmarkFieldIndex.ThreadID } ); + _thread = null; + } + + /// setups the sync logic for member _thread + /// Instance to set as the related entity of type entityType + private void SetupSyncThread(IEntity relatedEntity) + { + if(_thread!=relatedEntity) + { + DesetupSyncThread(true, true); + _thread = (ThreadEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", BookmarkEntity.Relations.ThreadEntityUsingThreadID, true, ref _alreadyFetchedThread, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnThreadPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _user + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncUser(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _user, new PropertyChangedEventHandler( OnUserPropertyChanged ), "User", BookmarkEntity.Relations.UserEntityUsingUserID, true, signalRelatedEntity, "Bookmarks", resetFKFields, new int[] { (int)BookmarkFieldIndex.UserID } ); + _user = null; + } + + /// setups the sync logic for member _user + /// Instance to set as the related entity of type entityType + private void SetupSyncUser(IEntity relatedEntity) + { + if(_user!=relatedEntity) + { + DesetupSyncUser(true, true); + _user = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _user, new PropertyChangedEventHandler( OnUserPropertyChanged ), "User", BookmarkEntity.Relations.UserEntityUsingUserID, true, ref _alreadyFetchedUser, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnUserPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 threadID, System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)BookmarkFieldIndex.ThreadID].ForcedCurrentValueWrite(threadID); + base.Fields[(int)BookmarkFieldIndex.UserID].ForcedCurrentValueWrite(userID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateBookmarkDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new BookmarkEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static BookmarkRelations Relations + { + get { return new BookmarkRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThread + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), + (IEntityRelation)GetRelationsForField("Thread")[0], (int)SD.HnD.DAL.EntityType.BookmarkEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, null, "Thread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("User")[0], (int)SD.HnD.DAL.EntityType.BookmarkEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "User", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "BookmarkEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return BookmarkEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return BookmarkEntity.FieldsCustomProperties;} + } + + /// The ThreadID property of the Entity Bookmark

+ ///
+ /// Mapped on table field: "Bookmark"."ThreadID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 ThreadID + { + get { return (System.Int32)GetValue((int)BookmarkFieldIndex.ThreadID, true); } + set { SetValue((int)BookmarkFieldIndex.ThreadID, value, true); } + } + /// The UserID property of the Entity Bookmark

+ ///
+ /// Mapped on table field: "Bookmark"."UserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 UserID + { + get { return (System.Int32)GetValue((int)BookmarkFieldIndex.UserID, true); } + set { SetValue((int)BookmarkFieldIndex.UserID, value, true); } + } + + + + /// Gets / sets related entity of type 'ThreadEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ThreadEntity Thread + { + get { return GetSingleThread(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncThread(value); + } + else + { + if(value==null) + { + if(_thread != null) + { + _thread.UnsetRelatedEntity(this, "PresentInBookmarks"); + } + } + else + { + if(_thread!=value) + { + ((IEntity)value).SetRelatedEntity(this, "PresentInBookmarks"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Thread. When set to true, Thread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Thread is accessed. You can always execute + /// a forced fetch by calling GetSingleThread(true). + [Browsable(false)] + public bool AlwaysFetchThread + { + get { return _alwaysFetchThread; } + set { _alwaysFetchThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property Thread already has been fetched. Setting this property to false when Thread has been fetched + /// will set Thread to null as well. Setting this property to true while Thread hasn't been fetched disables lazy loading for Thread + [Browsable(false)] + public bool AlreadyFetchedThread + { + get { return _alreadyFetchedThread;} + set + { + if(_alreadyFetchedThread && !value) + { + this.Thread = null; + } + _alreadyFetchedThread = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Thread is not found + /// in the database. When set to true, Thread will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ThreadReturnsNewIfNotFound + { + get { return _threadReturnsNewIfNotFound; } + set { _threadReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity User + { + get { return GetSingleUser(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncUser(value); + } + else + { + if(value==null) + { + if(_user != null) + { + _user.UnsetRelatedEntity(this, "Bookmarks"); + } + } + else + { + if(_user!=value) + { + ((IEntity)value).SetRelatedEntity(this, "Bookmarks"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for User. When set to true, User is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time User is accessed. You can always execute + /// a forced fetch by calling GetSingleUser(true). + [Browsable(false)] + public bool AlwaysFetchUser + { + get { return _alwaysFetchUser; } + set { _alwaysFetchUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property User already has been fetched. Setting this property to false when User has been fetched + /// will set User to null as well. Setting this property to true while User hasn't been fetched disables lazy loading for User + [Browsable(false)] + public bool AlreadyFetchedUser + { + get { return _alreadyFetchedUser;} + set + { + if(_alreadyFetchedUser && !value) + { + this.User = null; + } + _alreadyFetchedUser = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property User is not found + /// in the database. When set to true, User will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool UserReturnsNewIfNotFound + { + get { return _userReturnsNewIfNotFound; } + set { _userReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.BookmarkEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/ForumEntityBase.cs b/DAL/EntityBaseClasses/ForumEntityBase.cs new file mode 100644 index 0000000..57f2f30 --- /dev/null +++ b/DAL/EntityBaseClasses/ForumEntityBase.cs @@ -0,0 +1,1602 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'Forum'.

+ /// + ///
+ [Serializable] + public abstract partial class ForumEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection _forumRoleForumActionRights; + private bool _alwaysFetchForumRoleForumActionRights, _alreadyFetchedForumRoleForumActionRights; + private SD.HnD.DAL.CollectionClasses.ThreadCollection _threads; + private bool _alwaysFetchThreads, _alreadyFetchedThreads; + private SD.HnD.DAL.CollectionClasses.UserCollection _usersWhoStartedThreads; + private bool _alwaysFetchUsersWhoStartedThreads, _alreadyFetchedUsersWhoStartedThreads; + private SectionEntity _section; + private bool _alwaysFetchSection, _alreadyFetchedSection, _sectionReturnsNewIfNotFound; + private SupportQueueEntity _defaultSupportQueue; + private bool _alwaysFetchDefaultSupportQueue, _alreadyFetchedDefaultSupportQueue, _defaultSupportQueueReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name Section + public static readonly string Section = "Section"; + /// Member name DefaultSupportQueue + public static readonly string DefaultSupportQueue = "DefaultSupportQueue"; + /// Member name ForumRoleForumActionRights + public static readonly string ForumRoleForumActionRights = "ForumRoleForumActionRights"; + /// Member name Threads + public static readonly string Threads = "Threads"; + /// Member name UsersWhoStartedThreads + public static readonly string UsersWhoStartedThreads = "UsersWhoStartedThreads"; + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static ForumEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public ForumEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for Forum which data should be fetched into this Forum object + public ForumEntityBase(System.Int32 forumID) + { + InitClassFetch(forumID, null, null); + } + + /// CTor + /// PK value for Forum which data should be fetched into this Forum object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ForumEntityBase(System.Int32 forumID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(forumID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for Forum which data should be fetched into this Forum object + /// The custom validator object for this ForumEntity + public ForumEntityBase(System.Int32 forumID, IValidator validator) + { + InitClassFetch(forumID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected ForumEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _forumRoleForumActionRights = (SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection)info.GetValue("_forumRoleForumActionRights", typeof(SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection)); + _alwaysFetchForumRoleForumActionRights = info.GetBoolean("_alwaysFetchForumRoleForumActionRights"); + _alreadyFetchedForumRoleForumActionRights = info.GetBoolean("_alreadyFetchedForumRoleForumActionRights"); + _threads = (SD.HnD.DAL.CollectionClasses.ThreadCollection)info.GetValue("_threads", typeof(SD.HnD.DAL.CollectionClasses.ThreadCollection)); + _alwaysFetchThreads = info.GetBoolean("_alwaysFetchThreads"); + _alreadyFetchedThreads = info.GetBoolean("_alreadyFetchedThreads"); + _usersWhoStartedThreads = (SD.HnD.DAL.CollectionClasses.UserCollection)info.GetValue("_usersWhoStartedThreads", typeof(SD.HnD.DAL.CollectionClasses.UserCollection)); + _alwaysFetchUsersWhoStartedThreads = info.GetBoolean("_alwaysFetchUsersWhoStartedThreads"); + _alreadyFetchedUsersWhoStartedThreads = info.GetBoolean("_alreadyFetchedUsersWhoStartedThreads"); + _section = (SectionEntity)info.GetValue("_section", typeof(SectionEntity)); + if(_section!=null) + { + _section.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _sectionReturnsNewIfNotFound = info.GetBoolean("_sectionReturnsNewIfNotFound"); + _alwaysFetchSection = info.GetBoolean("_alwaysFetchSection"); + _alreadyFetchedSection = info.GetBoolean("_alreadyFetchedSection"); + _defaultSupportQueue = (SupportQueueEntity)info.GetValue("_defaultSupportQueue", typeof(SupportQueueEntity)); + if(_defaultSupportQueue!=null) + { + _defaultSupportQueue.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _defaultSupportQueueReturnsNewIfNotFound = info.GetBoolean("_defaultSupportQueueReturnsNewIfNotFound"); + _alwaysFetchDefaultSupportQueue = info.GetBoolean("_alwaysFetchDefaultSupportQueue"); + _alreadyFetchedDefaultSupportQueue = info.GetBoolean("_alreadyFetchedDefaultSupportQueue"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((ForumFieldIndex)fieldIndex) + { + case ForumFieldIndex.SectionID: + DesetupSyncSection(true, false); + _alreadyFetchedSection = false; + break; + case ForumFieldIndex.DefaultSupportQueueID: + DesetupSyncDefaultSupportQueue(true, false); + _alreadyFetchedDefaultSupportQueue = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedForumRoleForumActionRights = (_forumRoleForumActionRights.Count > 0); + _alreadyFetchedThreads = (_threads.Count > 0); + _alreadyFetchedUsersWhoStartedThreads = (_usersWhoStartedThreads.Count > 0); + _alreadyFetchedSection = (_section != null); + _alreadyFetchedDefaultSupportQueue = (_defaultSupportQueue != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return ForumEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "Section": + toReturn.Add(ForumEntity.Relations.SectionEntityUsingSectionID); + break; + case "DefaultSupportQueue": + toReturn.Add(ForumEntity.Relations.SupportQueueEntityUsingDefaultSupportQueueID); + break; + case "ForumRoleForumActionRights": + toReturn.Add(ForumEntity.Relations.ForumRoleForumActionRightEntityUsingForumID); + break; + case "Threads": + toReturn.Add(ForumEntity.Relations.ThreadEntityUsingForumID); + break; + case "UsersWhoStartedThreads": + toReturn.Add(ForumEntity.Relations.ThreadEntityUsingForumID, "ForumEntity__", "Thread_", JoinHint.None); + toReturn.Add(ThreadEntity.Relations.UserEntityUsingStartedByUserID, "Thread_", string.Empty, JoinHint.None); + break; + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_forumRoleForumActionRights", (!this.MarkedForDeletion?_forumRoleForumActionRights:null)); + info.AddValue("_alwaysFetchForumRoleForumActionRights", _alwaysFetchForumRoleForumActionRights); + info.AddValue("_alreadyFetchedForumRoleForumActionRights", _alreadyFetchedForumRoleForumActionRights); + info.AddValue("_threads", (!this.MarkedForDeletion?_threads:null)); + info.AddValue("_alwaysFetchThreads", _alwaysFetchThreads); + info.AddValue("_alreadyFetchedThreads", _alreadyFetchedThreads); + info.AddValue("_usersWhoStartedThreads", (!this.MarkedForDeletion?_usersWhoStartedThreads:null)); + info.AddValue("_alwaysFetchUsersWhoStartedThreads", _alwaysFetchUsersWhoStartedThreads); + info.AddValue("_alreadyFetchedUsersWhoStartedThreads", _alreadyFetchedUsersWhoStartedThreads); + info.AddValue("_section", (!this.MarkedForDeletion?_section:null)); + info.AddValue("_sectionReturnsNewIfNotFound", _sectionReturnsNewIfNotFound); + info.AddValue("_alwaysFetchSection", _alwaysFetchSection); + info.AddValue("_alreadyFetchedSection", _alreadyFetchedSection); + info.AddValue("_defaultSupportQueue", (!this.MarkedForDeletion?_defaultSupportQueue:null)); + info.AddValue("_defaultSupportQueueReturnsNewIfNotFound", _defaultSupportQueueReturnsNewIfNotFound); + info.AddValue("_alwaysFetchDefaultSupportQueue", _alwaysFetchDefaultSupportQueue); + info.AddValue("_alreadyFetchedDefaultSupportQueue", _alreadyFetchedDefaultSupportQueue); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "Section": + _alreadyFetchedSection = true; + this.Section = (SectionEntity)entity; + break; + case "DefaultSupportQueue": + _alreadyFetchedDefaultSupportQueue = true; + this.DefaultSupportQueue = (SupportQueueEntity)entity; + break; + case "ForumRoleForumActionRights": + _alreadyFetchedForumRoleForumActionRights = true; + if(entity!=null) + { + this.ForumRoleForumActionRights.Add((ForumRoleForumActionRightEntity)entity); + } + break; + case "Threads": + _alreadyFetchedThreads = true; + if(entity!=null) + { + this.Threads.Add((ThreadEntity)entity); + } + break; + case "UsersWhoStartedThreads": + _alreadyFetchedUsersWhoStartedThreads = true; + if(entity!=null) + { + this.UsersWhoStartedThreads.Add((UserEntity)entity); + } + break; + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "Section": + SetupSyncSection(relatedEntity); + break; + case "DefaultSupportQueue": + SetupSyncDefaultSupportQueue(relatedEntity); + break; + case "ForumRoleForumActionRights": + _forumRoleForumActionRights.Add((ForumRoleForumActionRightEntity)relatedEntity); + break; + case "Threads": + _threads.Add((ThreadEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "Section": + DesetupSyncSection(false, true); + break; + case "DefaultSupportQueue": + DesetupSyncDefaultSupportQueue(false, true); + break; + case "ForumRoleForumActionRights": + base.PerformRelatedEntityRemoval(_forumRoleForumActionRights, relatedEntity, signalRelatedEntityManyToOne); + break; + case "Threads": + base.PerformRelatedEntityRemoval(_threads, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_section!=null) + { + toReturn.Add(_section); + } + if(_defaultSupportQueue!=null) + { + toReturn.Add(_defaultSupportQueue); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_forumRoleForumActionRights); + toReturn.Add(_threads); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Forum which data should be fetched into this Forum object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 forumID) + { + return FetchUsingPK(forumID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Forum which data should be fetched into this Forum object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 forumID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(forumID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Forum which data should be fetched into this Forum object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 forumID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(forumID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Forum which data should be fetched into this Forum object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 forumID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(forumID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.ForumID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(ForumFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(ForumFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new ForumRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ForumRoleForumActionRightEntity' + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch) + { + return GetMultiForumRoleForumActionRights(forceFetch, _forumRoleForumActionRights.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ForumRoleForumActionRightEntity' + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IPredicateExpression filter) + { + return GetMultiForumRoleForumActionRights(forceFetch, _forumRoleForumActionRights.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiForumRoleForumActionRights(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedForumRoleForumActionRights || forceFetch || _alwaysFetchForumRoleForumActionRights) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_forumRoleForumActionRights.ParticipatesInTransaction) + { + base.Transaction.Add(_forumRoleForumActionRights); + } + } + _forumRoleForumActionRights.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _forumRoleForumActionRights.EntityFactoryToUse = entityFactoryToUse; + } + _forumRoleForumActionRights.GetMultiManyToOne(null, this, null, filter); + _forumRoleForumActionRights.SuppressClearInGetMulti=false; + _alreadyFetchedForumRoleForumActionRights = true; + } + return _forumRoleForumActionRights; + } + + /// Sets the collection parameters for the collection for 'ForumRoleForumActionRights'. These settings will be taken into account + /// when the property ForumRoleForumActionRights is requested or GetMultiForumRoleForumActionRights is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersForumRoleForumActionRights(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _forumRoleForumActionRights.SortClauses=sortClauses; + _forumRoleForumActionRights.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ThreadEntity' + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiThreads(bool forceFetch) + { + return GetMultiThreads(forceFetch, _threads.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ThreadEntity' + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiThreads(bool forceFetch, IPredicateExpression filter) + { + return GetMultiThreads(forceFetch, _threads.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiThreads(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiThreads(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiThreads(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedThreads || forceFetch || _alwaysFetchThreads) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_threads.ParticipatesInTransaction) + { + base.Transaction.Add(_threads); + } + } + _threads.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _threads.EntityFactoryToUse = entityFactoryToUse; + } + _threads.GetMultiManyToOne(this, null, filter); + _threads.SuppressClearInGetMulti=false; + _alreadyFetchedThreads = true; + } + return _threads; + } + + /// Sets the collection parameters for the collection for 'Threads'. These settings will be taken into account + /// when the property Threads is requested or GetMultiThreads is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersThreads(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _threads.SortClauses=sortClauses; + _threads.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'UserEntity' + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsersWhoStartedThreads(bool forceFetch) + { + return GetMultiUsersWhoStartedThreads(forceFetch, _usersWhoStartedThreads.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsersWhoStartedThreads(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedUsersWhoStartedThreads || forceFetch || _alwaysFetchUsersWhoStartedThreads) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_usersWhoStartedThreads.ParticipatesInTransaction) + { + base.Transaction.Add(_usersWhoStartedThreads); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(ForumFields.ForumID, ComparisonOperator.Equal, this.ForumID, "ForumEntity__")); + _usersWhoStartedThreads.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _usersWhoStartedThreads.EntityFactoryToUse = entityFactoryToUse; + } + _usersWhoStartedThreads.GetMulti(filter, GetRelationsForField("UsersWhoStartedThreads")); + _usersWhoStartedThreads.SuppressClearInGetMulti=false; + _alreadyFetchedUsersWhoStartedThreads = true; + } + return _usersWhoStartedThreads; + } + + /// Sets the collection parameters for the collection for 'UsersWhoStartedThreads'. These settings will be taken into account + /// when the property UsersWhoStartedThreads is requested or GetMultiUsersWhoStartedThreads is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersUsersWhoStartedThreads(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _usersWhoStartedThreads.SortClauses=sortClauses; + _usersWhoStartedThreads.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves the related entity of type 'SectionEntity', using a relation of type 'n:1' + /// A fetched entity of type 'SectionEntity' which is related to this entity. + public SectionEntity GetSingleSection() + { + return GetSingleSection(false); + } + + /// Retrieves the related entity of type 'SectionEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'SectionEntity' which is related to this entity. + public virtual SectionEntity GetSingleSection(bool forceFetch) + { + if( ( !_alreadyFetchedSection || forceFetch || _alwaysFetchSection) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ForumEntity.Relations.SectionEntityUsingSectionID); + + SectionEntity newEntity = new SectionEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.SectionID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (SectionEntity)base.ActiveContext.Get(newEntity); + } + this.Section = newEntity; + } + else + { + if(_sectionReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_section == null))) + { + this.Section = newEntity; + } + } + else + { + this.Section = null; + } + } + _alreadyFetchedSection = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _section; + } + + /// Retrieves the related entity of type 'SupportQueueEntity', using a relation of type 'n:1' + /// A fetched entity of type 'SupportQueueEntity' which is related to this entity. + public SupportQueueEntity GetSingleDefaultSupportQueue() + { + return GetSingleDefaultSupportQueue(false); + } + + /// Retrieves the related entity of type 'SupportQueueEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'SupportQueueEntity' which is related to this entity. + public virtual SupportQueueEntity GetSingleDefaultSupportQueue(bool forceFetch) + { + if( ( !_alreadyFetchedDefaultSupportQueue || forceFetch || _alwaysFetchDefaultSupportQueue) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ForumEntity.Relations.SupportQueueEntityUsingDefaultSupportQueueID); + + SupportQueueEntity newEntity = new SupportQueueEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.DefaultSupportQueueID.GetValueOrDefault()); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (SupportQueueEntity)base.ActiveContext.Get(newEntity); + } + this.DefaultSupportQueue = newEntity; + } + else + { + if(_defaultSupportQueueReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_defaultSupportQueue == null))) + { + this.DefaultSupportQueue = newEntity; + } + } + else + { + this.DefaultSupportQueue = null; + } + } + _alreadyFetchedDefaultSupportQueue = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _defaultSupportQueue; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + ForumDAO dao = (ForumDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _forumRoleForumActionRights.ActiveContext = base.ActiveContext; + _threads.ActiveContext = base.ActiveContext; + _usersWhoStartedThreads.ActiveContext = base.ActiveContext; + if(_section!=null) + { + _section.ActiveContext = base.ActiveContext; + } + if(_defaultSupportQueue!=null) + { + _defaultSupportQueue.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + ForumDAO dao = (ForumDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + ForumDAO dao = (ForumDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("Section", _section); + toReturn.Add("DefaultSupportQueue", _defaultSupportQueue); + toReturn.Add("ForumRoleForumActionRights", _forumRoleForumActionRights); + toReturn.Add("Threads", _threads); + toReturn.Add("UsersWhoStartedThreads", _usersWhoStartedThreads); + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for Forum which data should be fetched into this Forum object + /// The validator object for this ForumEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 forumID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(forumID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _forumRoleForumActionRights = new SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection(new ForumRoleForumActionRightEntityFactory()); + _forumRoleForumActionRights.SetContainingEntityInfo(this, "Forum"); + _alwaysFetchForumRoleForumActionRights = false; + _alreadyFetchedForumRoleForumActionRights = false; + _threads = new SD.HnD.DAL.CollectionClasses.ThreadCollection(new ThreadEntityFactory()); + _threads.SetContainingEntityInfo(this, "Forum"); + _alwaysFetchThreads = false; + _alreadyFetchedThreads = false; + _usersWhoStartedThreads = new SD.HnD.DAL.CollectionClasses.UserCollection(new UserEntityFactory()); + _alwaysFetchUsersWhoStartedThreads = false; + _alreadyFetchedUsersWhoStartedThreads = false; + _section = null; + _sectionReturnsNewIfNotFound = true; + _alwaysFetchSection = false; + _alreadyFetchedSection = false; + _defaultSupportQueue = null; + _defaultSupportQueueReturnsNewIfNotFound = true; + _alwaysFetchDefaultSupportQueue = false; + _alreadyFetchedDefaultSupportQueue = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ForumID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("SectionID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ForumName", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ForumDescription", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ForumLastPostingDate", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("HasRSSFeed", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("DefaultSupportQueueID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("DefaultThreadListInterval", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("OrderNo", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MaxAttachmentSize", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MaxNoOfAttachmentsPerMessage", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("NewThreadWelcomeText", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("NewThreadWelcomeTextAsHTML", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _section + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncSection(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _section, new PropertyChangedEventHandler( OnSectionPropertyChanged ), "Section", ForumEntity.Relations.SectionEntityUsingSectionID, true, signalRelatedEntity, "Forums", resetFKFields, new int[] { (int)ForumFieldIndex.SectionID } ); + _section = null; + } + + /// setups the sync logic for member _section + /// Instance to set as the related entity of type entityType + private void SetupSyncSection(IEntity relatedEntity) + { + if(_section!=relatedEntity) + { + DesetupSyncSection(true, true); + _section = (SectionEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _section, new PropertyChangedEventHandler( OnSectionPropertyChanged ), "Section", ForumEntity.Relations.SectionEntityUsingSectionID, true, ref _alreadyFetchedSection, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnSectionPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _defaultSupportQueue + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncDefaultSupportQueue(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _defaultSupportQueue, new PropertyChangedEventHandler( OnDefaultSupportQueuePropertyChanged ), "DefaultSupportQueue", ForumEntity.Relations.SupportQueueEntityUsingDefaultSupportQueueID, true, signalRelatedEntity, "DefaultForForums", resetFKFields, new int[] { (int)ForumFieldIndex.DefaultSupportQueueID } ); + _defaultSupportQueue = null; + } + + /// setups the sync logic for member _defaultSupportQueue + /// Instance to set as the related entity of type entityType + private void SetupSyncDefaultSupportQueue(IEntity relatedEntity) + { + if(_defaultSupportQueue!=relatedEntity) + { + DesetupSyncDefaultSupportQueue(true, true); + _defaultSupportQueue = (SupportQueueEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _defaultSupportQueue, new PropertyChangedEventHandler( OnDefaultSupportQueuePropertyChanged ), "DefaultSupportQueue", ForumEntity.Relations.SupportQueueEntityUsingDefaultSupportQueueID, true, ref _alreadyFetchedDefaultSupportQueue, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnDefaultSupportQueuePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for Forum which data should be fetched into this Forum object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 forumID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)ForumFieldIndex.ForumID].ForcedCurrentValueWrite(forumID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateForumDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new ForumEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static ForumRelations Relations + { + get { return new ForumRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'ForumRoleForumActionRight' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathForumRoleForumActionRights + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection(), + (IEntityRelation)GetRelationsForField("ForumRoleForumActionRights")[0], (int)SD.HnD.DAL.EntityType.ForumEntity, (int)SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity, 0, null, null, null, "ForumRoleForumActionRights", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThreads + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), + (IEntityRelation)GetRelationsForField("Threads")[0], (int)SD.HnD.DAL.EntityType.ForumEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, null, "Threads", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUsersWhoStartedThreads + { + get + { + IEntityRelation intermediateRelation = ForumEntity.Relations.ThreadEntityUsingForumID; + intermediateRelation.SetAliases(string.Empty, "Thread_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.ForumEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, GetRelationsForField("UsersWhoStartedThreads"), "UsersWhoStartedThreads", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Section' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSection + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SectionCollection(), + (IEntityRelation)GetRelationsForField("Section")[0], (int)SD.HnD.DAL.EntityType.ForumEntity, (int)SD.HnD.DAL.EntityType.SectionEntity, 0, null, null, null, "Section", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'SupportQueue' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathDefaultSupportQueue + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SupportQueueCollection(), + (IEntityRelation)GetRelationsForField("DefaultSupportQueue")[0], (int)SD.HnD.DAL.EntityType.ForumEntity, (int)SD.HnD.DAL.EntityType.SupportQueueEntity, 0, null, null, null, "DefaultSupportQueue", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "ForumEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return ForumEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return ForumEntity.FieldsCustomProperties;} + } + + /// The ForumID property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."ForumID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 ForumID + { + get { return (System.Int32)GetValue((int)ForumFieldIndex.ForumID, true); } + set { SetValue((int)ForumFieldIndex.ForumID, value, true); } + } + /// The SectionID property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."SectionID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 SectionID + { + get { return (System.Int32)GetValue((int)ForumFieldIndex.SectionID, true); } + set { SetValue((int)ForumFieldIndex.SectionID, value, true); } + } + /// The ForumName property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."ForumName"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 50
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String ForumName + { + get { return (System.String)GetValue((int)ForumFieldIndex.ForumName, true); } + set { SetValue((int)ForumFieldIndex.ForumName, value, true); } + } + /// The ForumDescription property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."ForumDescription"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 250
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String ForumDescription + { + get { return (System.String)GetValue((int)ForumFieldIndex.ForumDescription, true); } + set { SetValue((int)ForumFieldIndex.ForumDescription, value, true); } + } + /// The ForumLastPostingDate property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."ForumLastPostingDate"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable ForumLastPostingDate + { + get { return (Nullable)GetValue((int)ForumFieldIndex.ForumLastPostingDate, false); } + set { SetValue((int)ForumFieldIndex.ForumLastPostingDate, value, true); } + } + /// The HasRSSFeed property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."HasRSSFeed"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean HasRSSFeed + { + get { return (System.Boolean)GetValue((int)ForumFieldIndex.HasRSSFeed, true); } + set { SetValue((int)ForumFieldIndex.HasRSSFeed, value, true); } + } + /// The DefaultSupportQueueID property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."DefaultSupportQueueID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable DefaultSupportQueueID + { + get { return (Nullable)GetValue((int)ForumFieldIndex.DefaultSupportQueueID, false); } + set { SetValue((int)ForumFieldIndex.DefaultSupportQueueID, value, true); } + } + /// The DefaultThreadListInterval property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."DefaultThreadListInterval"
+ /// Table field type characteristics (type, precision, scale, length): TinyInt, 3, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Byte DefaultThreadListInterval + { + get { return (System.Byte)GetValue((int)ForumFieldIndex.DefaultThreadListInterval, true); } + set { SetValue((int)ForumFieldIndex.DefaultThreadListInterval, value, true); } + } + /// The OrderNo property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."OrderNo"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int16 OrderNo + { + get { return (System.Int16)GetValue((int)ForumFieldIndex.OrderNo, true); } + set { SetValue((int)ForumFieldIndex.OrderNo, value, true); } + } + /// The MaxAttachmentSize property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."MaxAttachmentSize"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.Int32 MaxAttachmentSize + { + get { return (System.Int32)GetValue((int)ForumFieldIndex.MaxAttachmentSize, true); } + set { SetValue((int)ForumFieldIndex.MaxAttachmentSize, value, true); } + } + /// The MaxNoOfAttachmentsPerMessage property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."MaxNoOfAttachmentsPerMessage"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.Int16 MaxNoOfAttachmentsPerMessage + { + get { return (System.Int16)GetValue((int)ForumFieldIndex.MaxNoOfAttachmentsPerMessage, true); } + set { SetValue((int)ForumFieldIndex.MaxNoOfAttachmentsPerMessage, value, true); } + } + /// The NewThreadWelcomeText property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."NewThreadWelcomeText"
+ /// Table field type characteristics (type, precision, scale, length): NText, 0, 0, 1073741823
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String NewThreadWelcomeText + { + get { return (System.String)GetValue((int)ForumFieldIndex.NewThreadWelcomeText, true); } + set { SetValue((int)ForumFieldIndex.NewThreadWelcomeText, value, true); } + } + /// The NewThreadWelcomeTextAsHTML property of the Entity Forum

+ ///
+ /// Mapped on table field: "Forum"."NewThreadWelcomeTextAsHTML"
+ /// Table field type characteristics (type, precision, scale, length): NText, 0, 0, 1073741823
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String NewThreadWelcomeTextAsHTML + { + get { return (System.String)GetValue((int)ForumFieldIndex.NewThreadWelcomeTextAsHTML, true); } + set { SetValue((int)ForumFieldIndex.NewThreadWelcomeTextAsHTML, value, true); } + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiForumRoleForumActionRights()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection ForumRoleForumActionRights + { + get { return GetMultiForumRoleForumActionRights(false); } + } + + /// Gets / sets the lazy loading flag for ForumRoleForumActionRights. When set to true, ForumRoleForumActionRights is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ForumRoleForumActionRights is accessed. You can always execute + /// a forced fetch by calling GetMultiForumRoleForumActionRights(true). + [Browsable(false)] + public bool AlwaysFetchForumRoleForumActionRights + { + get { return _alwaysFetchForumRoleForumActionRights; } + set { _alwaysFetchForumRoleForumActionRights = value; } + } + + /// Gets / Sets the lazy loading flag if the property ForumRoleForumActionRights already has been fetched. Setting this property to false when ForumRoleForumActionRights has been fetched + /// will clear the ForumRoleForumActionRights collection well. Setting this property to true while ForumRoleForumActionRights hasn't been fetched disables lazy loading for ForumRoleForumActionRights + [Browsable(false)] + public bool AlreadyFetchedForumRoleForumActionRights + { + get { return _alreadyFetchedForumRoleForumActionRights;} + set + { + if(_alreadyFetchedForumRoleForumActionRights && !value && (_forumRoleForumActionRights != null)) + { + _forumRoleForumActionRights.Clear(); + } + _alreadyFetchedForumRoleForumActionRights = value; + } + } + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiThreads()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ThreadCollection Threads + { + get { return GetMultiThreads(false); } + } + + /// Gets / sets the lazy loading flag for Threads. When set to true, Threads is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Threads is accessed. You can always execute + /// a forced fetch by calling GetMultiThreads(true). + [Browsable(false)] + public bool AlwaysFetchThreads + { + get { return _alwaysFetchThreads; } + set { _alwaysFetchThreads = value; } + } + + /// Gets / Sets the lazy loading flag if the property Threads already has been fetched. Setting this property to false when Threads has been fetched + /// will clear the Threads collection well. Setting this property to true while Threads hasn't been fetched disables lazy loading for Threads + [Browsable(false)] + public bool AlreadyFetchedThreads + { + get { return _alreadyFetchedThreads;} + set + { + if(_alreadyFetchedThreads && !value && (_threads != null)) + { + _threads.Clear(); + } + _alreadyFetchedThreads = value; + } + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiUsersWhoStartedThreads()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.UserCollection UsersWhoStartedThreads + { + get { return GetMultiUsersWhoStartedThreads(false); } + } + + /// Gets / sets the lazy loading flag for UsersWhoStartedThreads. When set to true, UsersWhoStartedThreads is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time UsersWhoStartedThreads is accessed. You can always execute + /// a forced fetch by calling GetMultiUsersWhoStartedThreads(true). + [Browsable(false)] + public bool AlwaysFetchUsersWhoStartedThreads + { + get { return _alwaysFetchUsersWhoStartedThreads; } + set { _alwaysFetchUsersWhoStartedThreads = value; } + } + + /// Gets / Sets the lazy loading flag if the property UsersWhoStartedThreads already has been fetched. Setting this property to false when UsersWhoStartedThreads has been fetched + /// will clear the UsersWhoStartedThreads collection well. Setting this property to true while UsersWhoStartedThreads hasn't been fetched disables lazy loading for UsersWhoStartedThreads + [Browsable(false)] + public bool AlreadyFetchedUsersWhoStartedThreads + { + get { return _alreadyFetchedUsersWhoStartedThreads;} + set + { + if(_alreadyFetchedUsersWhoStartedThreads && !value && (_usersWhoStartedThreads != null)) + { + _usersWhoStartedThreads.Clear(); + } + _alreadyFetchedUsersWhoStartedThreads = value; + } + } + + /// Gets / sets related entity of type 'SectionEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleSection()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual SectionEntity Section + { + get { return GetSingleSection(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncSection(value); + } + else + { + if(value==null) + { + if(_section != null) + { + _section.UnsetRelatedEntity(this, "Forums"); + } + } + else + { + if(_section!=value) + { + ((IEntity)value).SetRelatedEntity(this, "Forums"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Section. When set to true, Section is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Section is accessed. You can always execute + /// a forced fetch by calling GetSingleSection(true). + [Browsable(false)] + public bool AlwaysFetchSection + { + get { return _alwaysFetchSection; } + set { _alwaysFetchSection = value; } + } + + /// Gets / Sets the lazy loading flag if the property Section already has been fetched. Setting this property to false when Section has been fetched + /// will set Section to null as well. Setting this property to true while Section hasn't been fetched disables lazy loading for Section + [Browsable(false)] + public bool AlreadyFetchedSection + { + get { return _alreadyFetchedSection;} + set + { + if(_alreadyFetchedSection && !value) + { + this.Section = null; + } + _alreadyFetchedSection = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Section is not found + /// in the database. When set to true, Section will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool SectionReturnsNewIfNotFound + { + get { return _sectionReturnsNewIfNotFound; } + set { _sectionReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'SupportQueueEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleDefaultSupportQueue()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual SupportQueueEntity DefaultSupportQueue + { + get { return GetSingleDefaultSupportQueue(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncDefaultSupportQueue(value); + } + else + { + if(value==null) + { + if(_defaultSupportQueue != null) + { + _defaultSupportQueue.UnsetRelatedEntity(this, "DefaultForForums"); + } + } + else + { + if(_defaultSupportQueue!=value) + { + ((IEntity)value).SetRelatedEntity(this, "DefaultForForums"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for DefaultSupportQueue. When set to true, DefaultSupportQueue is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time DefaultSupportQueue is accessed. You can always execute + /// a forced fetch by calling GetSingleDefaultSupportQueue(true). + [Browsable(false)] + public bool AlwaysFetchDefaultSupportQueue + { + get { return _alwaysFetchDefaultSupportQueue; } + set { _alwaysFetchDefaultSupportQueue = value; } + } + + /// Gets / Sets the lazy loading flag if the property DefaultSupportQueue already has been fetched. Setting this property to false when DefaultSupportQueue has been fetched + /// will set DefaultSupportQueue to null as well. Setting this property to true while DefaultSupportQueue hasn't been fetched disables lazy loading for DefaultSupportQueue + [Browsable(false)] + public bool AlreadyFetchedDefaultSupportQueue + { + get { return _alreadyFetchedDefaultSupportQueue;} + set + { + if(_alreadyFetchedDefaultSupportQueue && !value) + { + this.DefaultSupportQueue = null; + } + _alreadyFetchedDefaultSupportQueue = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property DefaultSupportQueue is not found + /// in the database. When set to true, DefaultSupportQueue will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool DefaultSupportQueueReturnsNewIfNotFound + { + get { return _defaultSupportQueueReturnsNewIfNotFound; } + set { _defaultSupportQueueReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.ForumEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/ForumRoleForumActionRightEntityBase.cs b/DAL/EntityBaseClasses/ForumRoleForumActionRightEntityBase.cs new file mode 100644 index 0000000..a4e09c8 --- /dev/null +++ b/DAL/EntityBaseClasses/ForumRoleForumActionRightEntityBase.cs @@ -0,0 +1,1332 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'ForumRoleForumActionRight'.

+ /// + ///
+ [Serializable] + public abstract partial class ForumRoleForumActionRightEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private ActionRightEntity _actionRight; + private bool _alwaysFetchActionRight, _alreadyFetchedActionRight, _actionRightReturnsNewIfNotFound; + private ForumEntity _forum; + private bool _alwaysFetchForum, _alreadyFetchedForum, _forumReturnsNewIfNotFound; + private RoleEntity _role; + private bool _alwaysFetchRole, _alreadyFetchedRole, _roleReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name ActionRight + public static readonly string ActionRight = "ActionRight"; + /// Member name Forum + public static readonly string Forum = "Forum"; + /// Member name Role + public static readonly string Role = "Role"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static ForumRoleForumActionRightEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public ForumRoleForumActionRightEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + public ForumRoleForumActionRightEntityBase(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID) + { + InitClassFetch(forumID, roleID, actionRightID, null, null); + } + + /// CTor + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ForumRoleForumActionRightEntityBase(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(forumID, roleID, actionRightID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// The custom validator object for this ForumRoleForumActionRightEntity + public ForumRoleForumActionRightEntityBase(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IValidator validator) + { + InitClassFetch(forumID, roleID, actionRightID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected ForumRoleForumActionRightEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _actionRight = (ActionRightEntity)info.GetValue("_actionRight", typeof(ActionRightEntity)); + if(_actionRight!=null) + { + _actionRight.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _actionRightReturnsNewIfNotFound = info.GetBoolean("_actionRightReturnsNewIfNotFound"); + _alwaysFetchActionRight = info.GetBoolean("_alwaysFetchActionRight"); + _alreadyFetchedActionRight = info.GetBoolean("_alreadyFetchedActionRight"); + _forum = (ForumEntity)info.GetValue("_forum", typeof(ForumEntity)); + if(_forum!=null) + { + _forum.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _forumReturnsNewIfNotFound = info.GetBoolean("_forumReturnsNewIfNotFound"); + _alwaysFetchForum = info.GetBoolean("_alwaysFetchForum"); + _alreadyFetchedForum = info.GetBoolean("_alreadyFetchedForum"); + _role = (RoleEntity)info.GetValue("_role", typeof(RoleEntity)); + if(_role!=null) + { + _role.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _roleReturnsNewIfNotFound = info.GetBoolean("_roleReturnsNewIfNotFound"); + _alwaysFetchRole = info.GetBoolean("_alwaysFetchRole"); + _alreadyFetchedRole = info.GetBoolean("_alreadyFetchedRole"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((ForumRoleForumActionRightFieldIndex)fieldIndex) + { + case ForumRoleForumActionRightFieldIndex.ForumID: + DesetupSyncForum(true, false); + _alreadyFetchedForum = false; + break; + case ForumRoleForumActionRightFieldIndex.RoleID: + DesetupSyncRole(true, false); + _alreadyFetchedRole = false; + break; + case ForumRoleForumActionRightFieldIndex.ActionRightID: + DesetupSyncActionRight(true, false); + _alreadyFetchedActionRight = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedActionRight = (_actionRight != null); + _alreadyFetchedForum = (_forum != null); + _alreadyFetchedRole = (_role != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return ForumRoleForumActionRightEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "ActionRight": + toReturn.Add(ForumRoleForumActionRightEntity.Relations.ActionRightEntityUsingActionRightID); + break; + case "Forum": + toReturn.Add(ForumRoleForumActionRightEntity.Relations.ForumEntityUsingForumID); + break; + case "Role": + toReturn.Add(ForumRoleForumActionRightEntity.Relations.RoleEntityUsingRoleID); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_actionRight", (!this.MarkedForDeletion?_actionRight:null)); + info.AddValue("_actionRightReturnsNewIfNotFound", _actionRightReturnsNewIfNotFound); + info.AddValue("_alwaysFetchActionRight", _alwaysFetchActionRight); + info.AddValue("_alreadyFetchedActionRight", _alreadyFetchedActionRight); + info.AddValue("_forum", (!this.MarkedForDeletion?_forum:null)); + info.AddValue("_forumReturnsNewIfNotFound", _forumReturnsNewIfNotFound); + info.AddValue("_alwaysFetchForum", _alwaysFetchForum); + info.AddValue("_alreadyFetchedForum", _alreadyFetchedForum); + info.AddValue("_role", (!this.MarkedForDeletion?_role:null)); + info.AddValue("_roleReturnsNewIfNotFound", _roleReturnsNewIfNotFound); + info.AddValue("_alwaysFetchRole", _alwaysFetchRole); + info.AddValue("_alreadyFetchedRole", _alreadyFetchedRole); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "ActionRight": + _alreadyFetchedActionRight = true; + this.ActionRight = (ActionRightEntity)entity; + break; + case "Forum": + _alreadyFetchedForum = true; + this.Forum = (ForumEntity)entity; + break; + case "Role": + _alreadyFetchedRole = true; + this.Role = (RoleEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "ActionRight": + SetupSyncActionRight(relatedEntity); + break; + case "Forum": + SetupSyncForum(relatedEntity); + break; + case "Role": + SetupSyncRole(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "ActionRight": + DesetupSyncActionRight(false, true); + break; + case "Forum": + DesetupSyncForum(false, true); + break; + case "Role": + DesetupSyncRole(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_actionRight!=null) + { + toReturn.Add(_actionRight); + } + if(_forum!=null) + { + toReturn.Add(_forum); + } + if(_role!=null) + { + toReturn.Add(_role); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID) + { + return FetchUsingPK(forumID, roleID, actionRightID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(forumID, roleID, actionRightID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(forumID, roleID, actionRightID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(forumID, roleID, actionRightID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.ForumID, this.RoleID, this.ActionRightID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(ForumRoleForumActionRightFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(ForumRoleForumActionRightFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new ForumRoleForumActionRightRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'ActionRightEntity', using a relation of type 'n:1' + /// A fetched entity of type 'ActionRightEntity' which is related to this entity. + public ActionRightEntity GetSingleActionRight() + { + return GetSingleActionRight(false); + } + + /// Retrieves the related entity of type 'ActionRightEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ActionRightEntity' which is related to this entity. + public virtual ActionRightEntity GetSingleActionRight(bool forceFetch) + { + if( ( !_alreadyFetchedActionRight || forceFetch || _alwaysFetchActionRight) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ForumRoleForumActionRightEntity.Relations.ActionRightEntityUsingActionRightID); + + ActionRightEntity newEntity = new ActionRightEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ActionRightID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (ActionRightEntity)base.ActiveContext.Get(newEntity); + } + this.ActionRight = newEntity; + } + else + { + if(_actionRightReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_actionRight == null))) + { + this.ActionRight = newEntity; + } + } + else + { + this.ActionRight = null; + } + } + _alreadyFetchedActionRight = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _actionRight; + } + + /// Retrieves the related entity of type 'ForumEntity', using a relation of type 'n:1' + /// A fetched entity of type 'ForumEntity' which is related to this entity. + public ForumEntity GetSingleForum() + { + return GetSingleForum(false); + } + + /// Retrieves the related entity of type 'ForumEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ForumEntity' which is related to this entity. + public virtual ForumEntity GetSingleForum(bool forceFetch) + { + if( ( !_alreadyFetchedForum || forceFetch || _alwaysFetchForum) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ForumRoleForumActionRightEntity.Relations.ForumEntityUsingForumID); + + ForumEntity newEntity = new ForumEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ForumID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (ForumEntity)base.ActiveContext.Get(newEntity); + } + this.Forum = newEntity; + } + else + { + if(_forumReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_forum == null))) + { + this.Forum = newEntity; + } + } + else + { + this.Forum = null; + } + } + _alreadyFetchedForum = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _forum; + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public RoleEntity GetSingleRole() + { + return GetSingleRole(false); + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public virtual RoleEntity GetSingleRole(bool forceFetch) + { + if( ( !_alreadyFetchedRole || forceFetch || _alwaysFetchRole) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ForumRoleForumActionRightEntity.Relations.RoleEntityUsingRoleID); + + RoleEntity newEntity = new RoleEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.RoleID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (RoleEntity)base.ActiveContext.Get(newEntity); + } + this.Role = newEntity; + } + else + { + if(_roleReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_role == null))) + { + this.Role = newEntity; + } + } + else + { + this.Role = null; + } + } + _alreadyFetchedRole = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _role; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + ForumRoleForumActionRightDAO dao = (ForumRoleForumActionRightDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_actionRight!=null) + { + _actionRight.ActiveContext = base.ActiveContext; + } + if(_forum!=null) + { + _forum.ActiveContext = base.ActiveContext; + } + if(_role!=null) + { + _role.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + ForumRoleForumActionRightDAO dao = (ForumRoleForumActionRightDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + ForumRoleForumActionRightDAO dao = (ForumRoleForumActionRightDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("ActionRight", _actionRight); + toReturn.Add("Forum", _forum); + toReturn.Add("Role", _role); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// The validator object for this ForumRoleForumActionRightEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(forumID, roleID, actionRightID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _actionRight = null; + _actionRightReturnsNewIfNotFound = true; + _alwaysFetchActionRight = false; + _alreadyFetchedActionRight = false; + _forum = null; + _forumReturnsNewIfNotFound = true; + _alwaysFetchForum = false; + _alreadyFetchedForum = false; + _role = null; + _roleReturnsNewIfNotFound = true; + _alwaysFetchRole = false; + _alreadyFetchedRole = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ForumID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("RoleID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ActionRightID", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _actionRight + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncActionRight(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _actionRight, new PropertyChangedEventHandler( OnActionRightPropertyChanged ), "ActionRight", ForumRoleForumActionRightEntity.Relations.ActionRightEntityUsingActionRightID, true, signalRelatedEntity, "ForumRoleForumActionRights", resetFKFields, new int[] { (int)ForumRoleForumActionRightFieldIndex.ActionRightID } ); + _actionRight = null; + } + + /// setups the sync logic for member _actionRight + /// Instance to set as the related entity of type entityType + private void SetupSyncActionRight(IEntity relatedEntity) + { + if(_actionRight!=relatedEntity) + { + DesetupSyncActionRight(true, true); + _actionRight = (ActionRightEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _actionRight, new PropertyChangedEventHandler( OnActionRightPropertyChanged ), "ActionRight", ForumRoleForumActionRightEntity.Relations.ActionRightEntityUsingActionRightID, true, ref _alreadyFetchedActionRight, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnActionRightPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _forum + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncForum(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _forum, new PropertyChangedEventHandler( OnForumPropertyChanged ), "Forum", ForumRoleForumActionRightEntity.Relations.ForumEntityUsingForumID, true, signalRelatedEntity, "ForumRoleForumActionRights", resetFKFields, new int[] { (int)ForumRoleForumActionRightFieldIndex.ForumID } ); + _forum = null; + } + + /// setups the sync logic for member _forum + /// Instance to set as the related entity of type entityType + private void SetupSyncForum(IEntity relatedEntity) + { + if(_forum!=relatedEntity) + { + DesetupSyncForum(true, true); + _forum = (ForumEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _forum, new PropertyChangedEventHandler( OnForumPropertyChanged ), "Forum", ForumRoleForumActionRightEntity.Relations.ForumEntityUsingForumID, true, ref _alreadyFetchedForum, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnForumPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _role + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncRole(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _role, new PropertyChangedEventHandler( OnRolePropertyChanged ), "Role", ForumRoleForumActionRightEntity.Relations.RoleEntityUsingRoleID, true, signalRelatedEntity, "ForumRoleForumActionRights", resetFKFields, new int[] { (int)ForumRoleForumActionRightFieldIndex.RoleID } ); + _role = null; + } + + /// setups the sync logic for member _role + /// Instance to set as the related entity of type entityType + private void SetupSyncRole(IEntity relatedEntity) + { + if(_role!=relatedEntity) + { + DesetupSyncRole(true, true); + _role = (RoleEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _role, new PropertyChangedEventHandler( OnRolePropertyChanged ), "Role", ForumRoleForumActionRightEntity.Relations.RoleEntityUsingRoleID, true, ref _alreadyFetchedRole, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnRolePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)ForumRoleForumActionRightFieldIndex.ForumID].ForcedCurrentValueWrite(forumID); + base.Fields[(int)ForumRoleForumActionRightFieldIndex.RoleID].ForcedCurrentValueWrite(roleID); + base.Fields[(int)ForumRoleForumActionRightFieldIndex.ActionRightID].ForcedCurrentValueWrite(actionRightID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateForumRoleForumActionRightDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new ForumRoleForumActionRightEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static ForumRoleForumActionRightRelations Relations + { + get { return new ForumRoleForumActionRightRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'ActionRight' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathActionRight + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ActionRightCollection(), + (IEntityRelation)GetRelationsForField("ActionRight")[0], (int)SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity, (int)SD.HnD.DAL.EntityType.ActionRightEntity, 0, null, null, null, "ActionRight", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Forum' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathForum + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ForumCollection(), + (IEntityRelation)GetRelationsForField("Forum")[0], (int)SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity, (int)SD.HnD.DAL.EntityType.ForumEntity, 0, null, null, null, "Forum", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRole + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), + (IEntityRelation)GetRelationsForField("Role")[0], (int)SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, null, "Role", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "ForumRoleForumActionRightEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return ForumRoleForumActionRightEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return ForumRoleForumActionRightEntity.FieldsCustomProperties;} + } + + /// The ForumID property of the Entity ForumRoleForumActionRight

+ ///
+ /// Mapped on table field: "ForumRoleForumActionRight"."ForumID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 ForumID + { + get { return (System.Int32)GetValue((int)ForumRoleForumActionRightFieldIndex.ForumID, true); } + set { SetValue((int)ForumRoleForumActionRightFieldIndex.ForumID, value, true); } + } + /// The RoleID property of the Entity ForumRoleForumActionRight

+ ///
+ /// Mapped on table field: "ForumRoleForumActionRight"."RoleID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 RoleID + { + get { return (System.Int32)GetValue((int)ForumRoleForumActionRightFieldIndex.RoleID, true); } + set { SetValue((int)ForumRoleForumActionRightFieldIndex.RoleID, value, true); } + } + /// The ActionRightID property of the Entity ForumRoleForumActionRight

+ ///
+ /// Mapped on table field: "ForumRoleForumActionRight"."ActionRightID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 ActionRightID + { + get { return (System.Int32)GetValue((int)ForumRoleForumActionRightFieldIndex.ActionRightID, true); } + set { SetValue((int)ForumRoleForumActionRightFieldIndex.ActionRightID, value, true); } + } + + + + /// Gets / sets related entity of type 'ActionRightEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleActionRight()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ActionRightEntity ActionRight + { + get { return GetSingleActionRight(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncActionRight(value); + } + else + { + if(value==null) + { + if(_actionRight != null) + { + _actionRight.UnsetRelatedEntity(this, "ForumRoleForumActionRights"); + } + } + else + { + if(_actionRight!=value) + { + ((IEntity)value).SetRelatedEntity(this, "ForumRoleForumActionRights"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for ActionRight. When set to true, ActionRight is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ActionRight is accessed. You can always execute + /// a forced fetch by calling GetSingleActionRight(true). + [Browsable(false)] + public bool AlwaysFetchActionRight + { + get { return _alwaysFetchActionRight; } + set { _alwaysFetchActionRight = value; } + } + + /// Gets / Sets the lazy loading flag if the property ActionRight already has been fetched. Setting this property to false when ActionRight has been fetched + /// will set ActionRight to null as well. Setting this property to true while ActionRight hasn't been fetched disables lazy loading for ActionRight + [Browsable(false)] + public bool AlreadyFetchedActionRight + { + get { return _alreadyFetchedActionRight;} + set + { + if(_alreadyFetchedActionRight && !value) + { + this.ActionRight = null; + } + _alreadyFetchedActionRight = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property ActionRight is not found + /// in the database. When set to true, ActionRight will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ActionRightReturnsNewIfNotFound + { + get { return _actionRightReturnsNewIfNotFound; } + set { _actionRightReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'ForumEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleForum()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ForumEntity Forum + { + get { return GetSingleForum(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncForum(value); + } + else + { + if(value==null) + { + if(_forum != null) + { + _forum.UnsetRelatedEntity(this, "ForumRoleForumActionRights"); + } + } + else + { + if(_forum!=value) + { + ((IEntity)value).SetRelatedEntity(this, "ForumRoleForumActionRights"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Forum. When set to true, Forum is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Forum is accessed. You can always execute + /// a forced fetch by calling GetSingleForum(true). + [Browsable(false)] + public bool AlwaysFetchForum + { + get { return _alwaysFetchForum; } + set { _alwaysFetchForum = value; } + } + + /// Gets / Sets the lazy loading flag if the property Forum already has been fetched. Setting this property to false when Forum has been fetched + /// will set Forum to null as well. Setting this property to true while Forum hasn't been fetched disables lazy loading for Forum + [Browsable(false)] + public bool AlreadyFetchedForum + { + get { return _alreadyFetchedForum;} + set + { + if(_alreadyFetchedForum && !value) + { + this.Forum = null; + } + _alreadyFetchedForum = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Forum is not found + /// in the database. When set to true, Forum will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ForumReturnsNewIfNotFound + { + get { return _forumReturnsNewIfNotFound; } + set { _forumReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'RoleEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleRole()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual RoleEntity Role + { + get { return GetSingleRole(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncRole(value); + } + else + { + if(value==null) + { + if(_role != null) + { + _role.UnsetRelatedEntity(this, "ForumRoleForumActionRights"); + } + } + else + { + if(_role!=value) + { + ((IEntity)value).SetRelatedEntity(this, "ForumRoleForumActionRights"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Role. When set to true, Role is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Role is accessed. You can always execute + /// a forced fetch by calling GetSingleRole(true). + [Browsable(false)] + public bool AlwaysFetchRole + { + get { return _alwaysFetchRole; } + set { _alwaysFetchRole = value; } + } + + /// Gets / Sets the lazy loading flag if the property Role already has been fetched. Setting this property to false when Role has been fetched + /// will set Role to null as well. Setting this property to true while Role hasn't been fetched disables lazy loading for Role + [Browsable(false)] + public bool AlreadyFetchedRole + { + get { return _alreadyFetchedRole;} + set + { + if(_alreadyFetchedRole && !value) + { + this.Role = null; + } + _alreadyFetchedRole = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Role is not found + /// in the database. When set to true, Role will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool RoleReturnsNewIfNotFound + { + get { return _roleReturnsNewIfNotFound; } + set { _roleReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/IPBanEntityBase.cs b/DAL/EntityBaseClasses/IPBanEntityBase.cs new file mode 100644 index 0000000..0481d23 --- /dev/null +++ b/DAL/EntityBaseClasses/IPBanEntityBase.cs @@ -0,0 +1,970 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'IPBan'.

+ /// + ///
+ [Serializable] + public abstract partial class IPBanEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private UserEntity _setByUser; + private bool _alwaysFetchSetByUser, _alreadyFetchedSetByUser, _setByUserReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name SetByUser + public static readonly string SetByUser = "SetByUser"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static IPBanEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public IPBanEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for IPBan which data should be fetched into this IPBan object + public IPBanEntityBase(System.Int32 iPBanID) + { + InitClassFetch(iPBanID, null, null); + } + + /// CTor + /// PK value for IPBan which data should be fetched into this IPBan object + /// the PrefetchPath which defines the graph of objects to fetch as well + public IPBanEntityBase(System.Int32 iPBanID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(iPBanID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for IPBan which data should be fetched into this IPBan object + /// The custom validator object for this IPBanEntity + public IPBanEntityBase(System.Int32 iPBanID, IValidator validator) + { + InitClassFetch(iPBanID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected IPBanEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _setByUser = (UserEntity)info.GetValue("_setByUser", typeof(UserEntity)); + if(_setByUser!=null) + { + _setByUser.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _setByUserReturnsNewIfNotFound = info.GetBoolean("_setByUserReturnsNewIfNotFound"); + _alwaysFetchSetByUser = info.GetBoolean("_alwaysFetchSetByUser"); + _alreadyFetchedSetByUser = info.GetBoolean("_alreadyFetchedSetByUser"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((IPBanFieldIndex)fieldIndex) + { + case IPBanFieldIndex.IPBanSetByUserID: + DesetupSyncSetByUser(true, false); + _alreadyFetchedSetByUser = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedSetByUser = (_setByUser != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return IPBanEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "SetByUser": + toReturn.Add(IPBanEntity.Relations.UserEntityUsingIPBanSetByUserID); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_setByUser", (!this.MarkedForDeletion?_setByUser:null)); + info.AddValue("_setByUserReturnsNewIfNotFound", _setByUserReturnsNewIfNotFound); + info.AddValue("_alwaysFetchSetByUser", _alwaysFetchSetByUser); + info.AddValue("_alreadyFetchedSetByUser", _alreadyFetchedSetByUser); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "SetByUser": + _alreadyFetchedSetByUser = true; + this.SetByUser = (UserEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "SetByUser": + SetupSyncSetByUser(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "SetByUser": + DesetupSyncSetByUser(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_setByUser!=null) + { + toReturn.Add(_setByUser); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for IPBan which data should be fetched into this IPBan object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 iPBanID) + { + return FetchUsingPK(iPBanID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for IPBan which data should be fetched into this IPBan object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 iPBanID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(iPBanID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for IPBan which data should be fetched into this IPBan object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 iPBanID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(iPBanID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for IPBan which data should be fetched into this IPBan object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 iPBanID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(iPBanID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.IPBanID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(IPBanFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(IPBanFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new IPBanRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSingleSetByUser() + { + return GetSingleSetByUser(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSingleSetByUser(bool forceFetch) + { + if( ( !_alreadyFetchedSetByUser || forceFetch || _alwaysFetchSetByUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(IPBanEntity.Relations.UserEntityUsingIPBanSetByUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.IPBanSetByUserID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.SetByUser = newEntity; + } + else + { + if(_setByUserReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_setByUser == null))) + { + this.SetByUser = newEntity; + } + } + else + { + this.SetByUser = null; + } + } + _alreadyFetchedSetByUser = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _setByUser; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + IPBanDAO dao = (IPBanDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_setByUser!=null) + { + _setByUser.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + IPBanDAO dao = (IPBanDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + IPBanDAO dao = (IPBanDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.IPBanEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("SetByUser", _setByUser); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for IPBan which data should be fetched into this IPBan object + /// The validator object for this IPBanEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 iPBanID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(iPBanID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _setByUser = null; + _setByUserReturnsNewIfNotFound = true; + _alwaysFetchSetByUser = false; + _alreadyFetchedSetByUser = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IPBanID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IPSegment1", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IPSegment2", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IPSegment3", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IPSegment4", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Range", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IPBanSetByUserID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IPBanSetOn", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Reason", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _setByUser + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncSetByUser(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _setByUser, new PropertyChangedEventHandler( OnSetByUserPropertyChanged ), "SetByUser", IPBanEntity.Relations.UserEntityUsingIPBanSetByUserID, true, signalRelatedEntity, "IPBansSet", resetFKFields, new int[] { (int)IPBanFieldIndex.IPBanSetByUserID } ); + _setByUser = null; + } + + /// setups the sync logic for member _setByUser + /// Instance to set as the related entity of type entityType + private void SetupSyncSetByUser(IEntity relatedEntity) + { + if(_setByUser!=relatedEntity) + { + DesetupSyncSetByUser(true, true); + _setByUser = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _setByUser, new PropertyChangedEventHandler( OnSetByUserPropertyChanged ), "SetByUser", IPBanEntity.Relations.UserEntityUsingIPBanSetByUserID, true, ref _alreadyFetchedSetByUser, new string[] { "SetByUserNickName" } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnSetByUserPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + case "NickName": + base.OnPropertyChanged("SetByUserNickName"); + break; + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for IPBan which data should be fetched into this IPBan object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 iPBanID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)IPBanFieldIndex.IPBanID].ForcedCurrentValueWrite(iPBanID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateIPBanDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new IPBanEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static IPBanRelations Relations + { + get { return new IPBanRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSetByUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("SetByUser")[0], (int)SD.HnD.DAL.EntityType.IPBanEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "SetByUser", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "IPBanEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return IPBanEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return IPBanEntity.FieldsCustomProperties;} + } + + /// The IPBanID property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."IPBanID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 IPBanID + { + get { return (System.Int32)GetValue((int)IPBanFieldIndex.IPBanID, true); } + set { SetValue((int)IPBanFieldIndex.IPBanID, value, true); } + } + /// The IPSegment1 property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."IPSegment1"
+ /// Table field type characteristics (type, precision, scale, length): TinyInt, 3, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Byte IPSegment1 + { + get { return (System.Byte)GetValue((int)IPBanFieldIndex.IPSegment1, true); } + set { SetValue((int)IPBanFieldIndex.IPSegment1, value, true); } + } + /// The IPSegment2 property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."IPSegment2"
+ /// Table field type characteristics (type, precision, scale, length): TinyInt, 3, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Byte IPSegment2 + { + get { return (System.Byte)GetValue((int)IPBanFieldIndex.IPSegment2, true); } + set { SetValue((int)IPBanFieldIndex.IPSegment2, value, true); } + } + /// The IPSegment3 property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."IPSegment3"
+ /// Table field type characteristics (type, precision, scale, length): TinyInt, 3, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Byte IPSegment3 + { + get { return (System.Byte)GetValue((int)IPBanFieldIndex.IPSegment3, true); } + set { SetValue((int)IPBanFieldIndex.IPSegment3, value, true); } + } + /// The IPSegment4 property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."IPSegment4"
+ /// Table field type characteristics (type, precision, scale, length): TinyInt, 3, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Byte IPSegment4 + { + get { return (System.Byte)GetValue((int)IPBanFieldIndex.IPSegment4, true); } + set { SetValue((int)IPBanFieldIndex.IPSegment4, value, true); } + } + /// The Range property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."Range"
+ /// Table field type characteristics (type, precision, scale, length): TinyInt, 3, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Byte Range + { + get { return (System.Byte)GetValue((int)IPBanFieldIndex.Range, true); } + set { SetValue((int)IPBanFieldIndex.Range, value, true); } + } + /// The IPBanSetByUserID property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."IPBanSetByUserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 IPBanSetByUserID + { + get { return (System.Int32)GetValue((int)IPBanFieldIndex.IPBanSetByUserID, true); } + set { SetValue((int)IPBanFieldIndex.IPBanSetByUserID, value, true); } + } + /// The IPBanSetOn property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."IPBanSetOn"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.DateTime IPBanSetOn + { + get { return (System.DateTime)GetValue((int)IPBanFieldIndex.IPBanSetOn, true); } + set { SetValue((int)IPBanFieldIndex.IPBanSetOn, value, true); } + } + /// The Reason property of the Entity IPBan

+ ///
+ /// Mapped on table field: "IPBan"."Reason"
+ /// Table field type characteristics (type, precision, scale, length): NText, 0, 0, 1073741823
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String Reason + { + get { return (System.String)GetValue((int)IPBanFieldIndex.Reason, true); } + set { SetValue((int)IPBanFieldIndex.Reason, value, true); } + } + + + + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleSetByUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity SetByUser + { + get { return GetSingleSetByUser(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncSetByUser(value); + } + else + { + if(value==null) + { + if(_setByUser != null) + { + _setByUser.UnsetRelatedEntity(this, "IPBansSet"); + } + } + else + { + if(_setByUser!=value) + { + ((IEntity)value).SetRelatedEntity(this, "IPBansSet"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for SetByUser. When set to true, SetByUser is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SetByUser is accessed. You can always execute + /// a forced fetch by calling GetSingleSetByUser(true). + [Browsable(false)] + public bool AlwaysFetchSetByUser + { + get { return _alwaysFetchSetByUser; } + set { _alwaysFetchSetByUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property SetByUser already has been fetched. Setting this property to false when SetByUser has been fetched + /// will set SetByUser to null as well. Setting this property to true while SetByUser hasn't been fetched disables lazy loading for SetByUser + [Browsable(false)] + public bool AlreadyFetchedSetByUser + { + get { return _alreadyFetchedSetByUser;} + set + { + if(_alreadyFetchedSetByUser && !value) + { + this.SetByUser = null; + } + _alreadyFetchedSetByUser = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property SetByUser is not found + /// in the database. When set to true, SetByUser will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool SetByUserReturnsNewIfNotFound + { + get { return _setByUserReturnsNewIfNotFound; } + set { _setByUserReturnsNewIfNotFound = value; } + } + + + /// Gets the value of the related field this.SetByUser.NickName. + public virtual System.String SetByUserNickName + { + get + { + UserEntity relatedEntity = this.SetByUser; + if(relatedEntity!=null) + { + return relatedEntity.NickName; + } + else + { + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + } + + } + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.IPBanEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/MessageEntityBase.cs b/DAL/EntityBaseClasses/MessageEntityBase.cs new file mode 100644 index 0000000..8ed6c53 --- /dev/null +++ b/DAL/EntityBaseClasses/MessageEntityBase.cs @@ -0,0 +1,1441 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'Message'.

+ /// + ///
+ [Serializable] + public abstract partial class MessageEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.AttachmentCollection _attachments; + private bool _alwaysFetchAttachments, _alreadyFetchedAttachments; + private SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection _auditDataMessageRelated; + private bool _alwaysFetchAuditDataMessageRelated, _alreadyFetchedAuditDataMessageRelated; + + private ThreadEntity _thread; + private bool _alwaysFetchThread, _alreadyFetchedThread, _threadReturnsNewIfNotFound; + private UserEntity _postedByUser; + private bool _alwaysFetchPostedByUser, _alreadyFetchedPostedByUser, _postedByUserReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name Thread + public static readonly string Thread = "Thread"; + /// Member name PostedByUser + public static readonly string PostedByUser = "PostedByUser"; + /// Member name Attachments + public static readonly string Attachments = "Attachments"; + /// Member name AuditDataMessageRelated + public static readonly string AuditDataMessageRelated = "AuditDataMessageRelated"; + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static MessageEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public MessageEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for Message which data should be fetched into this Message object + public MessageEntityBase(System.Int32 messageID) + { + InitClassFetch(messageID, null, null); + } + + /// CTor + /// PK value for Message which data should be fetched into this Message object + /// the PrefetchPath which defines the graph of objects to fetch as well + public MessageEntityBase(System.Int32 messageID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(messageID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for Message which data should be fetched into this Message object + /// The custom validator object for this MessageEntity + public MessageEntityBase(System.Int32 messageID, IValidator validator) + { + InitClassFetch(messageID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected MessageEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _attachments = (SD.HnD.DAL.CollectionClasses.AttachmentCollection)info.GetValue("_attachments", typeof(SD.HnD.DAL.CollectionClasses.AttachmentCollection)); + _alwaysFetchAttachments = info.GetBoolean("_alwaysFetchAttachments"); + _alreadyFetchedAttachments = info.GetBoolean("_alreadyFetchedAttachments"); + _auditDataMessageRelated = (SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection)info.GetValue("_auditDataMessageRelated", typeof(SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection)); + _alwaysFetchAuditDataMessageRelated = info.GetBoolean("_alwaysFetchAuditDataMessageRelated"); + _alreadyFetchedAuditDataMessageRelated = info.GetBoolean("_alreadyFetchedAuditDataMessageRelated"); + + _thread = (ThreadEntity)info.GetValue("_thread", typeof(ThreadEntity)); + if(_thread!=null) + { + _thread.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _threadReturnsNewIfNotFound = info.GetBoolean("_threadReturnsNewIfNotFound"); + _alwaysFetchThread = info.GetBoolean("_alwaysFetchThread"); + _alreadyFetchedThread = info.GetBoolean("_alreadyFetchedThread"); + _postedByUser = (UserEntity)info.GetValue("_postedByUser", typeof(UserEntity)); + if(_postedByUser!=null) + { + _postedByUser.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _postedByUserReturnsNewIfNotFound = info.GetBoolean("_postedByUserReturnsNewIfNotFound"); + _alwaysFetchPostedByUser = info.GetBoolean("_alwaysFetchPostedByUser"); + _alreadyFetchedPostedByUser = info.GetBoolean("_alreadyFetchedPostedByUser"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((MessageFieldIndex)fieldIndex) + { + case MessageFieldIndex.PostedByUserID: + DesetupSyncPostedByUser(true, false); + _alreadyFetchedPostedByUser = false; + break; + case MessageFieldIndex.ThreadID: + DesetupSyncThread(true, false); + _alreadyFetchedThread = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedAttachments = (_attachments.Count > 0); + _alreadyFetchedAuditDataMessageRelated = (_auditDataMessageRelated.Count > 0); + + _alreadyFetchedThread = (_thread != null); + _alreadyFetchedPostedByUser = (_postedByUser != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return MessageEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "Thread": + toReturn.Add(MessageEntity.Relations.ThreadEntityUsingThreadID); + break; + case "PostedByUser": + toReturn.Add(MessageEntity.Relations.UserEntityUsingPostedByUserID); + break; + case "Attachments": + toReturn.Add(MessageEntity.Relations.AttachmentEntityUsingMessageID); + break; + case "AuditDataMessageRelated": + toReturn.Add(MessageEntity.Relations.AuditDataMessageRelatedEntityUsingMessageID); + break; + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_attachments", (!this.MarkedForDeletion?_attachments:null)); + info.AddValue("_alwaysFetchAttachments", _alwaysFetchAttachments); + info.AddValue("_alreadyFetchedAttachments", _alreadyFetchedAttachments); + info.AddValue("_auditDataMessageRelated", (!this.MarkedForDeletion?_auditDataMessageRelated:null)); + info.AddValue("_alwaysFetchAuditDataMessageRelated", _alwaysFetchAuditDataMessageRelated); + info.AddValue("_alreadyFetchedAuditDataMessageRelated", _alreadyFetchedAuditDataMessageRelated); + + info.AddValue("_thread", (!this.MarkedForDeletion?_thread:null)); + info.AddValue("_threadReturnsNewIfNotFound", _threadReturnsNewIfNotFound); + info.AddValue("_alwaysFetchThread", _alwaysFetchThread); + info.AddValue("_alreadyFetchedThread", _alreadyFetchedThread); + info.AddValue("_postedByUser", (!this.MarkedForDeletion?_postedByUser:null)); + info.AddValue("_postedByUserReturnsNewIfNotFound", _postedByUserReturnsNewIfNotFound); + info.AddValue("_alwaysFetchPostedByUser", _alwaysFetchPostedByUser); + info.AddValue("_alreadyFetchedPostedByUser", _alreadyFetchedPostedByUser); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "Thread": + _alreadyFetchedThread = true; + this.Thread = (ThreadEntity)entity; + break; + case "PostedByUser": + _alreadyFetchedPostedByUser = true; + this.PostedByUser = (UserEntity)entity; + break; + case "Attachments": + _alreadyFetchedAttachments = true; + if(entity!=null) + { + this.Attachments.Add((AttachmentEntity)entity); + } + break; + case "AuditDataMessageRelated": + _alreadyFetchedAuditDataMessageRelated = true; + if(entity!=null) + { + this.AuditDataMessageRelated.Add((AuditDataMessageRelatedEntity)entity); + } + break; + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "Thread": + SetupSyncThread(relatedEntity); + break; + case "PostedByUser": + SetupSyncPostedByUser(relatedEntity); + break; + case "Attachments": + _attachments.Add((AttachmentEntity)relatedEntity); + break; + case "AuditDataMessageRelated": + _auditDataMessageRelated.Add((AuditDataMessageRelatedEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "Thread": + DesetupSyncThread(false, true); + break; + case "PostedByUser": + DesetupSyncPostedByUser(false, true); + break; + case "Attachments": + base.PerformRelatedEntityRemoval(_attachments, relatedEntity, signalRelatedEntityManyToOne); + break; + case "AuditDataMessageRelated": + base.PerformRelatedEntityRemoval(_auditDataMessageRelated, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_thread!=null) + { + toReturn.Add(_thread); + } + if(_postedByUser!=null) + { + toReturn.Add(_postedByUser); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_attachments); + toReturn.Add(_auditDataMessageRelated); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Message which data should be fetched into this Message object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 messageID) + { + return FetchUsingPK(messageID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Message which data should be fetched into this Message object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 messageID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(messageID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Message which data should be fetched into this Message object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 messageID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(messageID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Message which data should be fetched into this Message object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 messageID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(messageID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.MessageID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(MessageFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(MessageFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new MessageRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'AttachmentEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'AttachmentEntity' + public SD.HnD.DAL.CollectionClasses.AttachmentCollection GetMultiAttachments(bool forceFetch) + { + return GetMultiAttachments(forceFetch, _attachments.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AttachmentEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'AttachmentEntity' + public SD.HnD.DAL.CollectionClasses.AttachmentCollection GetMultiAttachments(bool forceFetch, IPredicateExpression filter) + { + return GetMultiAttachments(forceFetch, _attachments.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'AttachmentEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.AttachmentCollection GetMultiAttachments(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiAttachments(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AttachmentEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.AttachmentCollection GetMultiAttachments(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedAttachments || forceFetch || _alwaysFetchAttachments) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_attachments.ParticipatesInTransaction) + { + base.Transaction.Add(_attachments); + } + } + _attachments.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _attachments.EntityFactoryToUse = entityFactoryToUse; + } + _attachments.GetMultiManyToOne(this, filter); + _attachments.SuppressClearInGetMulti=false; + _alreadyFetchedAttachments = true; + } + return _attachments; + } + + /// Sets the collection parameters for the collection for 'Attachments'. These settings will be taken into account + /// when the property Attachments is requested or GetMultiAttachments is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersAttachments(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _attachments.SortClauses=sortClauses; + _attachments.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'AuditDataMessageRelatedEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'AuditDataMessageRelatedEntity' + public SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection GetMultiAuditDataMessageRelated(bool forceFetch) + { + return GetMultiAuditDataMessageRelated(forceFetch, _auditDataMessageRelated.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AuditDataMessageRelatedEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'AuditDataMessageRelatedEntity' + public SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection GetMultiAuditDataMessageRelated(bool forceFetch, IPredicateExpression filter) + { + return GetMultiAuditDataMessageRelated(forceFetch, _auditDataMessageRelated.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'AuditDataMessageRelatedEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection GetMultiAuditDataMessageRelated(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiAuditDataMessageRelated(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AuditDataMessageRelatedEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection GetMultiAuditDataMessageRelated(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedAuditDataMessageRelated || forceFetch || _alwaysFetchAuditDataMessageRelated) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_auditDataMessageRelated.ParticipatesInTransaction) + { + base.Transaction.Add(_auditDataMessageRelated); + } + } + _auditDataMessageRelated.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _auditDataMessageRelated.EntityFactoryToUse = entityFactoryToUse; + } + _auditDataMessageRelated.GetMultiManyToOne(null, this, null, filter); + _auditDataMessageRelated.SuppressClearInGetMulti=false; + _alreadyFetchedAuditDataMessageRelated = true; + } + return _auditDataMessageRelated; + } + + /// Sets the collection parameters for the collection for 'AuditDataMessageRelated'. These settings will be taken into account + /// when the property AuditDataMessageRelated is requested or GetMultiAuditDataMessageRelated is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersAuditDataMessageRelated(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _auditDataMessageRelated.SortClauses=sortClauses; + _auditDataMessageRelated.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type 'n:1' + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public ThreadEntity GetSingleThread() + { + return GetSingleThread(false); + } + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public virtual ThreadEntity GetSingleThread(bool forceFetch) + { + if( ( !_alreadyFetchedThread || forceFetch || _alwaysFetchThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(MessageEntity.Relations.ThreadEntityUsingThreadID); + + ThreadEntity newEntity = new ThreadEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ThreadID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (ThreadEntity)base.ActiveContext.Get(newEntity); + } + this.Thread = newEntity; + } + else + { + if(_threadReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_thread == null))) + { + this.Thread = newEntity; + } + } + else + { + this.Thread = null; + } + } + _alreadyFetchedThread = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _thread; + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSinglePostedByUser() + { + return GetSinglePostedByUser(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSinglePostedByUser(bool forceFetch) + { + if( ( !_alreadyFetchedPostedByUser || forceFetch || _alwaysFetchPostedByUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(MessageEntity.Relations.UserEntityUsingPostedByUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.PostedByUserID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.PostedByUser = newEntity; + } + else + { + if(_postedByUserReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_postedByUser == null))) + { + this.PostedByUser = newEntity; + } + } + else + { + this.PostedByUser = null; + } + } + _alreadyFetchedPostedByUser = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _postedByUser; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + MessageDAO dao = (MessageDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _attachments.ActiveContext = base.ActiveContext; + _auditDataMessageRelated.ActiveContext = base.ActiveContext; + + if(_thread!=null) + { + _thread.ActiveContext = base.ActiveContext; + } + if(_postedByUser!=null) + { + _postedByUser.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + MessageDAO dao = (MessageDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + MessageDAO dao = (MessageDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.MessageEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("Thread", _thread); + toReturn.Add("PostedByUser", _postedByUser); + toReturn.Add("Attachments", _attachments); + toReturn.Add("AuditDataMessageRelated", _auditDataMessageRelated); + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for Message which data should be fetched into this Message object + /// The validator object for this MessageEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 messageID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(messageID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _attachments = new SD.HnD.DAL.CollectionClasses.AttachmentCollection(new AttachmentEntityFactory()); + _attachments.SetContainingEntityInfo(this, "BelongsToMessage"); + _alwaysFetchAttachments = false; + _alreadyFetchedAttachments = false; + _auditDataMessageRelated = new SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection(new AuditDataMessageRelatedEntityFactory()); + _auditDataMessageRelated.SetContainingEntityInfo(this, "Message"); + _alwaysFetchAuditDataMessageRelated = false; + _alreadyFetchedAuditDataMessageRelated = false; + + _thread = null; + _threadReturnsNewIfNotFound = true; + _alwaysFetchThread = false; + _alreadyFetchedThread = false; + _postedByUser = null; + _postedByUserReturnsNewIfNotFound = true; + _alwaysFetchPostedByUser = false; + _alreadyFetchedPostedByUser = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MessageID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("PostingDate", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("PostedByUserID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("PostedFromIP", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ChangeTrackerStamp", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MessageText", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MessageTextAsHTML", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MessageTextAsXml", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _thread + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncThread(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", MessageEntity.Relations.ThreadEntityUsingThreadID, true, signalRelatedEntity, "Messages", resetFKFields, new int[] { (int)MessageFieldIndex.ThreadID } ); + _thread = null; + } + + /// setups the sync logic for member _thread + /// Instance to set as the related entity of type entityType + private void SetupSyncThread(IEntity relatedEntity) + { + if(_thread!=relatedEntity) + { + DesetupSyncThread(true, true); + _thread = (ThreadEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", MessageEntity.Relations.ThreadEntityUsingThreadID, true, ref _alreadyFetchedThread, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnThreadPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _postedByUser + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncPostedByUser(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _postedByUser, new PropertyChangedEventHandler( OnPostedByUserPropertyChanged ), "PostedByUser", MessageEntity.Relations.UserEntityUsingPostedByUserID, true, signalRelatedEntity, "PostedMessages", resetFKFields, new int[] { (int)MessageFieldIndex.PostedByUserID } ); + _postedByUser = null; + } + + /// setups the sync logic for member _postedByUser + /// Instance to set as the related entity of type entityType + private void SetupSyncPostedByUser(IEntity relatedEntity) + { + if(_postedByUser!=relatedEntity) + { + DesetupSyncPostedByUser(true, true); + _postedByUser = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _postedByUser, new PropertyChangedEventHandler( OnPostedByUserPropertyChanged ), "PostedByUser", MessageEntity.Relations.UserEntityUsingPostedByUserID, true, ref _alreadyFetchedPostedByUser, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnPostedByUserPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for Message which data should be fetched into this Message object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 messageID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)MessageFieldIndex.MessageID].ForcedCurrentValueWrite(messageID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateMessageDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new MessageEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static MessageRelations Relations + { + get { return new MessageRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Attachment' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathAttachments + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.AttachmentCollection(), + (IEntityRelation)GetRelationsForField("Attachments")[0], (int)SD.HnD.DAL.EntityType.MessageEntity, (int)SD.HnD.DAL.EntityType.AttachmentEntity, 0, null, null, null, "Attachments", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'AuditDataMessageRelated' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathAuditDataMessageRelated + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection(), + (IEntityRelation)GetRelationsForField("AuditDataMessageRelated")[0], (int)SD.HnD.DAL.EntityType.MessageEntity, (int)SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity, 0, null, null, null, "AuditDataMessageRelated", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThread + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), + (IEntityRelation)GetRelationsForField("Thread")[0], (int)SD.HnD.DAL.EntityType.MessageEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, null, "Thread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathPostedByUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("PostedByUser")[0], (int)SD.HnD.DAL.EntityType.MessageEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "PostedByUser", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "MessageEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return MessageEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return MessageEntity.FieldsCustomProperties;} + } + + /// The MessageID property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."MessageID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 MessageID + { + get { return (System.Int32)GetValue((int)MessageFieldIndex.MessageID, true); } + set { SetValue((int)MessageFieldIndex.MessageID, value, true); } + } + /// The PostingDate property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."PostingDate"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.DateTime PostingDate + { + get { return (System.DateTime)GetValue((int)MessageFieldIndex.PostingDate, true); } + set { SetValue((int)MessageFieldIndex.PostingDate, value, true); } + } + /// The PostedByUserID property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."PostedByUserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 PostedByUserID + { + get { return (System.Int32)GetValue((int)MessageFieldIndex.PostedByUserID, true); } + set { SetValue((int)MessageFieldIndex.PostedByUserID, value, true); } + } + /// The ThreadID property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."ThreadID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 ThreadID + { + get { return (System.Int32)GetValue((int)MessageFieldIndex.ThreadID, true); } + set { SetValue((int)MessageFieldIndex.ThreadID, value, true); } + } + /// The PostedFromIP property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."PostedFromIP"
+ /// Table field type characteristics (type, precision, scale, length): VarChar, 0, 0, 25
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String PostedFromIP + { + get { return (System.String)GetValue((int)MessageFieldIndex.PostedFromIP, true); } + set { SetValue((int)MessageFieldIndex.PostedFromIP, value, true); } + } + /// The ChangeTrackerStamp property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."ChangeTrackerStamp"
+ /// Table field type characteristics (type, precision, scale, length): Timestamp, 0, 0, 8
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Byte[] ChangeTrackerStamp + { + get { return (System.Byte[])GetValue((int)MessageFieldIndex.ChangeTrackerStamp, true); } + + } + /// The MessageText property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."MessageText"
+ /// Table field type characteristics (type, precision, scale, length): NText, 0, 0, 1073741823
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String MessageText + { + get { return (System.String)GetValue((int)MessageFieldIndex.MessageText, true); } + set { SetValue((int)MessageFieldIndex.MessageText, value, true); } + } + /// The MessageTextAsHTML property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."MessageTextAsHTML"
+ /// Table field type characteristics (type, precision, scale, length): NText, 0, 0, 1073741823
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String MessageTextAsHTML + { + get { return (System.String)GetValue((int)MessageFieldIndex.MessageTextAsHTML, true); } + set { SetValue((int)MessageFieldIndex.MessageTextAsHTML, value, true); } + } + /// The MessageTextAsXml property of the Entity Message

+ ///
+ /// Mapped on table field: "Message"."MessageTextAsXml"
+ /// Table field type characteristics (type, precision, scale, length): NText, 0, 0, 1073741823
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String MessageTextAsXml + { + get { return (System.String)GetValue((int)MessageFieldIndex.MessageTextAsXml, true); } + set { SetValue((int)MessageFieldIndex.MessageTextAsXml, value, true); } + } + + /// Retrieves all related entities of type 'AttachmentEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiAttachments()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.AttachmentCollection Attachments + { + get { return GetMultiAttachments(false); } + } + + /// Gets / sets the lazy loading flag for Attachments. When set to true, Attachments is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Attachments is accessed. You can always execute + /// a forced fetch by calling GetMultiAttachments(true). + [Browsable(false)] + public bool AlwaysFetchAttachments + { + get { return _alwaysFetchAttachments; } + set { _alwaysFetchAttachments = value; } + } + + /// Gets / Sets the lazy loading flag if the property Attachments already has been fetched. Setting this property to false when Attachments has been fetched + /// will clear the Attachments collection well. Setting this property to true while Attachments hasn't been fetched disables lazy loading for Attachments + [Browsable(false)] + public bool AlreadyFetchedAttachments + { + get { return _alreadyFetchedAttachments;} + set + { + if(_alreadyFetchedAttachments && !value && (_attachments != null)) + { + _attachments.Clear(); + } + _alreadyFetchedAttachments = value; + } + } + /// Retrieves all related entities of type 'AuditDataMessageRelatedEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiAuditDataMessageRelated()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.AuditDataMessageRelatedCollection AuditDataMessageRelated + { + get { return GetMultiAuditDataMessageRelated(false); } + } + + /// Gets / sets the lazy loading flag for AuditDataMessageRelated. When set to true, AuditDataMessageRelated is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time AuditDataMessageRelated is accessed. You can always execute + /// a forced fetch by calling GetMultiAuditDataMessageRelated(true). + [Browsable(false)] + public bool AlwaysFetchAuditDataMessageRelated + { + get { return _alwaysFetchAuditDataMessageRelated; } + set { _alwaysFetchAuditDataMessageRelated = value; } + } + + /// Gets / Sets the lazy loading flag if the property AuditDataMessageRelated already has been fetched. Setting this property to false when AuditDataMessageRelated has been fetched + /// will clear the AuditDataMessageRelated collection well. Setting this property to true while AuditDataMessageRelated hasn't been fetched disables lazy loading for AuditDataMessageRelated + [Browsable(false)] + public bool AlreadyFetchedAuditDataMessageRelated + { + get { return _alreadyFetchedAuditDataMessageRelated;} + set + { + if(_alreadyFetchedAuditDataMessageRelated && !value && (_auditDataMessageRelated != null)) + { + _auditDataMessageRelated.Clear(); + } + _alreadyFetchedAuditDataMessageRelated = value; + } + } + + + /// Gets / sets related entity of type 'ThreadEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ThreadEntity Thread + { + get { return GetSingleThread(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncThread(value); + } + else + { + if(value==null) + { + if(_thread != null) + { + _thread.UnsetRelatedEntity(this, "Messages"); + } + } + else + { + if(_thread!=value) + { + ((IEntity)value).SetRelatedEntity(this, "Messages"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Thread. When set to true, Thread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Thread is accessed. You can always execute + /// a forced fetch by calling GetSingleThread(true). + [Browsable(false)] + public bool AlwaysFetchThread + { + get { return _alwaysFetchThread; } + set { _alwaysFetchThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property Thread already has been fetched. Setting this property to false when Thread has been fetched + /// will set Thread to null as well. Setting this property to true while Thread hasn't been fetched disables lazy loading for Thread + [Browsable(false)] + public bool AlreadyFetchedThread + { + get { return _alreadyFetchedThread;} + set + { + if(_alreadyFetchedThread && !value) + { + this.Thread = null; + } + _alreadyFetchedThread = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Thread is not found + /// in the database. When set to true, Thread will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ThreadReturnsNewIfNotFound + { + get { return _threadReturnsNewIfNotFound; } + set { _threadReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSinglePostedByUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity PostedByUser + { + get { return GetSinglePostedByUser(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncPostedByUser(value); + } + else + { + if(value==null) + { + if(_postedByUser != null) + { + _postedByUser.UnsetRelatedEntity(this, "PostedMessages"); + } + } + else + { + if(_postedByUser!=value) + { + ((IEntity)value).SetRelatedEntity(this, "PostedMessages"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for PostedByUser. When set to true, PostedByUser is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time PostedByUser is accessed. You can always execute + /// a forced fetch by calling GetSinglePostedByUser(true). + [Browsable(false)] + public bool AlwaysFetchPostedByUser + { + get { return _alwaysFetchPostedByUser; } + set { _alwaysFetchPostedByUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property PostedByUser already has been fetched. Setting this property to false when PostedByUser has been fetched + /// will set PostedByUser to null as well. Setting this property to true while PostedByUser hasn't been fetched disables lazy loading for PostedByUser + [Browsable(false)] + public bool AlreadyFetchedPostedByUser + { + get { return _alreadyFetchedPostedByUser;} + set + { + if(_alreadyFetchedPostedByUser && !value) + { + this.PostedByUser = null; + } + _alreadyFetchedPostedByUser = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property PostedByUser is not found + /// in the database. When set to true, PostedByUser will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool PostedByUserReturnsNewIfNotFound + { + get { return _postedByUserReturnsNewIfNotFound; } + set { _postedByUserReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.MessageEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/RoleAuditActionEntityBase.cs b/DAL/EntityBaseClasses/RoleAuditActionEntityBase.cs new file mode 100644 index 0000000..78cf1e5 --- /dev/null +++ b/DAL/EntityBaseClasses/RoleAuditActionEntityBase.cs @@ -0,0 +1,1089 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'RoleAuditAction'.

+ /// + ///
+ [Serializable] + public abstract partial class RoleAuditActionEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private AuditActionEntity _auditAction; + private bool _alwaysFetchAuditAction, _alreadyFetchedAuditAction, _auditActionReturnsNewIfNotFound; + private RoleEntity _role; + private bool _alwaysFetchRole, _alreadyFetchedRole, _roleReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name AuditAction + public static readonly string AuditAction = "AuditAction"; + /// Member name Role + public static readonly string Role = "Role"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static RoleAuditActionEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public RoleAuditActionEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + public RoleAuditActionEntityBase(System.Int32 auditActionID, System.Int32 roleID) + { + InitClassFetch(auditActionID, roleID, null, null); + } + + /// CTor + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + public RoleAuditActionEntityBase(System.Int32 auditActionID, System.Int32 roleID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(auditActionID, roleID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// The custom validator object for this RoleAuditActionEntity + public RoleAuditActionEntityBase(System.Int32 auditActionID, System.Int32 roleID, IValidator validator) + { + InitClassFetch(auditActionID, roleID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected RoleAuditActionEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _auditAction = (AuditActionEntity)info.GetValue("_auditAction", typeof(AuditActionEntity)); + if(_auditAction!=null) + { + _auditAction.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _auditActionReturnsNewIfNotFound = info.GetBoolean("_auditActionReturnsNewIfNotFound"); + _alwaysFetchAuditAction = info.GetBoolean("_alwaysFetchAuditAction"); + _alreadyFetchedAuditAction = info.GetBoolean("_alreadyFetchedAuditAction"); + _role = (RoleEntity)info.GetValue("_role", typeof(RoleEntity)); + if(_role!=null) + { + _role.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _roleReturnsNewIfNotFound = info.GetBoolean("_roleReturnsNewIfNotFound"); + _alwaysFetchRole = info.GetBoolean("_alwaysFetchRole"); + _alreadyFetchedRole = info.GetBoolean("_alreadyFetchedRole"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((RoleAuditActionFieldIndex)fieldIndex) + { + case RoleAuditActionFieldIndex.AuditActionID: + DesetupSyncAuditAction(true, false); + _alreadyFetchedAuditAction = false; + break; + case RoleAuditActionFieldIndex.RoleID: + DesetupSyncRole(true, false); + _alreadyFetchedRole = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedAuditAction = (_auditAction != null); + _alreadyFetchedRole = (_role != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return RoleAuditActionEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "AuditAction": + toReturn.Add(RoleAuditActionEntity.Relations.AuditActionEntityUsingAuditActionID); + break; + case "Role": + toReturn.Add(RoleAuditActionEntity.Relations.RoleEntityUsingRoleID); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_auditAction", (!this.MarkedForDeletion?_auditAction:null)); + info.AddValue("_auditActionReturnsNewIfNotFound", _auditActionReturnsNewIfNotFound); + info.AddValue("_alwaysFetchAuditAction", _alwaysFetchAuditAction); + info.AddValue("_alreadyFetchedAuditAction", _alreadyFetchedAuditAction); + info.AddValue("_role", (!this.MarkedForDeletion?_role:null)); + info.AddValue("_roleReturnsNewIfNotFound", _roleReturnsNewIfNotFound); + info.AddValue("_alwaysFetchRole", _alwaysFetchRole); + info.AddValue("_alreadyFetchedRole", _alreadyFetchedRole); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "AuditAction": + _alreadyFetchedAuditAction = true; + this.AuditAction = (AuditActionEntity)entity; + break; + case "Role": + _alreadyFetchedRole = true; + this.Role = (RoleEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "AuditAction": + SetupSyncAuditAction(relatedEntity); + break; + case "Role": + SetupSyncRole(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "AuditAction": + DesetupSyncAuditAction(false, true); + break; + case "Role": + DesetupSyncRole(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_auditAction!=null) + { + toReturn.Add(_auditAction); + } + if(_role!=null) + { + toReturn.Add(_role); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditActionID, System.Int32 roleID) + { + return FetchUsingPK(auditActionID, roleID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditActionID, System.Int32 roleID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(auditActionID, roleID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditActionID, System.Int32 roleID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(auditActionID, roleID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 auditActionID, System.Int32 roleID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(auditActionID, roleID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.AuditActionID, this.RoleID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(RoleAuditActionFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(RoleAuditActionFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new RoleAuditActionRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'AuditActionEntity', using a relation of type 'n:1' + /// A fetched entity of type 'AuditActionEntity' which is related to this entity. + public AuditActionEntity GetSingleAuditAction() + { + return GetSingleAuditAction(false); + } + + /// Retrieves the related entity of type 'AuditActionEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'AuditActionEntity' which is related to this entity. + public virtual AuditActionEntity GetSingleAuditAction(bool forceFetch) + { + if( ( !_alreadyFetchedAuditAction || forceFetch || _alwaysFetchAuditAction) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(RoleAuditActionEntity.Relations.AuditActionEntityUsingAuditActionID); + + AuditActionEntity newEntity = new AuditActionEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.AuditActionID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (AuditActionEntity)base.ActiveContext.Get(newEntity); + } + this.AuditAction = newEntity; + } + else + { + if(_auditActionReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_auditAction == null))) + { + this.AuditAction = newEntity; + } + } + else + { + this.AuditAction = null; + } + } + _alreadyFetchedAuditAction = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _auditAction; + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public RoleEntity GetSingleRole() + { + return GetSingleRole(false); + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public virtual RoleEntity GetSingleRole(bool forceFetch) + { + if( ( !_alreadyFetchedRole || forceFetch || _alwaysFetchRole) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(RoleAuditActionEntity.Relations.RoleEntityUsingRoleID); + + RoleEntity newEntity = new RoleEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.RoleID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (RoleEntity)base.ActiveContext.Get(newEntity); + } + this.Role = newEntity; + } + else + { + if(_roleReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_role == null))) + { + this.Role = newEntity; + } + } + else + { + this.Role = null; + } + } + _alreadyFetchedRole = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _role; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + RoleAuditActionDAO dao = (RoleAuditActionDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_auditAction!=null) + { + _auditAction.ActiveContext = base.ActiveContext; + } + if(_role!=null) + { + _role.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + RoleAuditActionDAO dao = (RoleAuditActionDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + RoleAuditActionDAO dao = (RoleAuditActionDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleAuditActionEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("AuditAction", _auditAction); + toReturn.Add("Role", _role); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// The validator object for this RoleAuditActionEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 auditActionID, System.Int32 roleID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(auditActionID, roleID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _auditAction = null; + _auditActionReturnsNewIfNotFound = true; + _alwaysFetchAuditAction = false; + _alreadyFetchedAuditAction = false; + _role = null; + _roleReturnsNewIfNotFound = true; + _alwaysFetchRole = false; + _alreadyFetchedRole = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AuditActionID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("RoleID", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _auditAction + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncAuditAction(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _auditAction, new PropertyChangedEventHandler( OnAuditActionPropertyChanged ), "AuditAction", RoleAuditActionEntity.Relations.AuditActionEntityUsingAuditActionID, true, signalRelatedEntity, "RoleAuditActions", resetFKFields, new int[] { (int)RoleAuditActionFieldIndex.AuditActionID } ); + _auditAction = null; + } + + /// setups the sync logic for member _auditAction + /// Instance to set as the related entity of type entityType + private void SetupSyncAuditAction(IEntity relatedEntity) + { + if(_auditAction!=relatedEntity) + { + DesetupSyncAuditAction(true, true); + _auditAction = (AuditActionEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _auditAction, new PropertyChangedEventHandler( OnAuditActionPropertyChanged ), "AuditAction", RoleAuditActionEntity.Relations.AuditActionEntityUsingAuditActionID, true, ref _alreadyFetchedAuditAction, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnAuditActionPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _role + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncRole(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _role, new PropertyChangedEventHandler( OnRolePropertyChanged ), "Role", RoleAuditActionEntity.Relations.RoleEntityUsingRoleID, true, signalRelatedEntity, "RoleAuditAction", resetFKFields, new int[] { (int)RoleAuditActionFieldIndex.RoleID } ); + _role = null; + } + + /// setups the sync logic for member _role + /// Instance to set as the related entity of type entityType + private void SetupSyncRole(IEntity relatedEntity) + { + if(_role!=relatedEntity) + { + DesetupSyncRole(true, true); + _role = (RoleEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _role, new PropertyChangedEventHandler( OnRolePropertyChanged ), "Role", RoleAuditActionEntity.Relations.RoleEntityUsingRoleID, true, ref _alreadyFetchedRole, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnRolePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 auditActionID, System.Int32 roleID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)RoleAuditActionFieldIndex.AuditActionID].ForcedCurrentValueWrite(auditActionID); + base.Fields[(int)RoleAuditActionFieldIndex.RoleID].ForcedCurrentValueWrite(roleID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateRoleAuditActionDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new RoleAuditActionEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static RoleAuditActionRelations Relations + { + get { return new RoleAuditActionRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'AuditAction' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathAuditAction + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.AuditActionCollection(), + (IEntityRelation)GetRelationsForField("AuditAction")[0], (int)SD.HnD.DAL.EntityType.RoleAuditActionEntity, (int)SD.HnD.DAL.EntityType.AuditActionEntity, 0, null, null, null, "AuditAction", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRole + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), + (IEntityRelation)GetRelationsForField("Role")[0], (int)SD.HnD.DAL.EntityType.RoleAuditActionEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, null, "Role", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "RoleAuditActionEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return RoleAuditActionEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return RoleAuditActionEntity.FieldsCustomProperties;} + } + + /// The AuditActionID property of the Entity RoleAuditAction

+ ///
+ /// Mapped on table field: "RoleAuditAction"."AuditActionID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 AuditActionID + { + get { return (System.Int32)GetValue((int)RoleAuditActionFieldIndex.AuditActionID, true); } + set { SetValue((int)RoleAuditActionFieldIndex.AuditActionID, value, true); } + } + /// The RoleID property of the Entity RoleAuditAction

+ ///
+ /// Mapped on table field: "RoleAuditAction"."RoleID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 RoleID + { + get { return (System.Int32)GetValue((int)RoleAuditActionFieldIndex.RoleID, true); } + set { SetValue((int)RoleAuditActionFieldIndex.RoleID, value, true); } + } + + + + /// Gets / sets related entity of type 'AuditActionEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleAuditAction()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual AuditActionEntity AuditAction + { + get { return GetSingleAuditAction(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncAuditAction(value); + } + else + { + if(value==null) + { + if(_auditAction != null) + { + _auditAction.UnsetRelatedEntity(this, "RoleAuditActions"); + } + } + else + { + if(_auditAction!=value) + { + ((IEntity)value).SetRelatedEntity(this, "RoleAuditActions"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for AuditAction. When set to true, AuditAction is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time AuditAction is accessed. You can always execute + /// a forced fetch by calling GetSingleAuditAction(true). + [Browsable(false)] + public bool AlwaysFetchAuditAction + { + get { return _alwaysFetchAuditAction; } + set { _alwaysFetchAuditAction = value; } + } + + /// Gets / Sets the lazy loading flag if the property AuditAction already has been fetched. Setting this property to false when AuditAction has been fetched + /// will set AuditAction to null as well. Setting this property to true while AuditAction hasn't been fetched disables lazy loading for AuditAction + [Browsable(false)] + public bool AlreadyFetchedAuditAction + { + get { return _alreadyFetchedAuditAction;} + set + { + if(_alreadyFetchedAuditAction && !value) + { + this.AuditAction = null; + } + _alreadyFetchedAuditAction = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property AuditAction is not found + /// in the database. When set to true, AuditAction will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool AuditActionReturnsNewIfNotFound + { + get { return _auditActionReturnsNewIfNotFound; } + set { _auditActionReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'RoleEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleRole()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual RoleEntity Role + { + get { return GetSingleRole(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncRole(value); + } + else + { + if(value==null) + { + if(_role != null) + { + _role.UnsetRelatedEntity(this, "RoleAuditAction"); + } + } + else + { + if(_role!=value) + { + ((IEntity)value).SetRelatedEntity(this, "RoleAuditAction"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Role. When set to true, Role is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Role is accessed. You can always execute + /// a forced fetch by calling GetSingleRole(true). + [Browsable(false)] + public bool AlwaysFetchRole + { + get { return _alwaysFetchRole; } + set { _alwaysFetchRole = value; } + } + + /// Gets / Sets the lazy loading flag if the property Role already has been fetched. Setting this property to false when Role has been fetched + /// will set Role to null as well. Setting this property to true while Role hasn't been fetched disables lazy loading for Role + [Browsable(false)] + public bool AlreadyFetchedRole + { + get { return _alreadyFetchedRole;} + set + { + if(_alreadyFetchedRole && !value) + { + this.Role = null; + } + _alreadyFetchedRole = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Role is not found + /// in the database. When set to true, Role will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool RoleReturnsNewIfNotFound + { + get { return _roleReturnsNewIfNotFound; } + set { _roleReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.RoleAuditActionEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/RoleEntityBase.cs b/DAL/EntityBaseClasses/RoleEntityBase.cs new file mode 100644 index 0000000..0f09a3d --- /dev/null +++ b/DAL/EntityBaseClasses/RoleEntityBase.cs @@ -0,0 +1,1849 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'Role'.

+ /// + ///
+ [Serializable] + public abstract partial class RoleEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection _forumRoleForumActionRights; + private bool _alwaysFetchForumRoleForumActionRights, _alreadyFetchedForumRoleForumActionRights; + private SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection _roleAuditAction; + private bool _alwaysFetchRoleAuditAction, _alreadyFetchedRoleAuditAction; + private SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection _roleSystemActionRights; + private bool _alwaysFetchRoleSystemActionRights, _alreadyFetchedRoleSystemActionRights; + private SD.HnD.DAL.CollectionClasses.RoleUserCollection _roleUser; + private bool _alwaysFetchRoleUser, _alreadyFetchedRoleUser; + private SD.HnD.DAL.CollectionClasses.SystemDataCollection _systemDataAnonymousRole; + private bool _alwaysFetchSystemDataAnonymousRole, _alreadyFetchedSystemDataAnonymousRole; + private SD.HnD.DAL.CollectionClasses.SystemDataCollection _systemDataDefaultRoleNewUser; + private bool _alwaysFetchSystemDataDefaultRoleNewUser, _alreadyFetchedSystemDataDefaultRoleNewUser; + private SD.HnD.DAL.CollectionClasses.ActionRightCollection _assignedSystemActionRights; + private bool _alwaysFetchAssignedSystemActionRights, _alreadyFetchedAssignedSystemActionRights; + private SD.HnD.DAL.CollectionClasses.AuditActionCollection _assignedAuditActions; + private bool _alwaysFetchAssignedAuditActions, _alreadyFetchedAssignedAuditActions; + private SD.HnD.DAL.CollectionClasses.UserCollection _users; + private bool _alwaysFetchUsers, _alreadyFetchedUsers; + + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + + /// Member name ForumRoleForumActionRights + public static readonly string ForumRoleForumActionRights = "ForumRoleForumActionRights"; + /// Member name RoleAuditAction + public static readonly string RoleAuditAction = "RoleAuditAction"; + /// Member name RoleSystemActionRights + public static readonly string RoleSystemActionRights = "RoleSystemActionRights"; + /// Member name RoleUser + public static readonly string RoleUser = "RoleUser"; + /// Member name SystemDataAnonymousRole + public static readonly string SystemDataAnonymousRole = "SystemDataAnonymousRole"; + /// Member name SystemDataDefaultRoleNewUser + public static readonly string SystemDataDefaultRoleNewUser = "SystemDataDefaultRoleNewUser"; + /// Member name AssignedSystemActionRights + public static readonly string AssignedSystemActionRights = "AssignedSystemActionRights"; + /// Member name AssignedAuditActions + public static readonly string AssignedAuditActions = "AssignedAuditActions"; + /// Member name Users + public static readonly string Users = "Users"; + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static RoleEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public RoleEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for Role which data should be fetched into this Role object + public RoleEntityBase(System.Int32 roleID) + { + InitClassFetch(roleID, null, null); + } + + /// CTor + /// PK value for Role which data should be fetched into this Role object + /// the PrefetchPath which defines the graph of objects to fetch as well + public RoleEntityBase(System.Int32 roleID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(roleID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for Role which data should be fetched into this Role object + /// The custom validator object for this RoleEntity + public RoleEntityBase(System.Int32 roleID, IValidator validator) + { + InitClassFetch(roleID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected RoleEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _forumRoleForumActionRights = (SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection)info.GetValue("_forumRoleForumActionRights", typeof(SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection)); + _alwaysFetchForumRoleForumActionRights = info.GetBoolean("_alwaysFetchForumRoleForumActionRights"); + _alreadyFetchedForumRoleForumActionRights = info.GetBoolean("_alreadyFetchedForumRoleForumActionRights"); + _roleAuditAction = (SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection)info.GetValue("_roleAuditAction", typeof(SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection)); + _alwaysFetchRoleAuditAction = info.GetBoolean("_alwaysFetchRoleAuditAction"); + _alreadyFetchedRoleAuditAction = info.GetBoolean("_alreadyFetchedRoleAuditAction"); + _roleSystemActionRights = (SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection)info.GetValue("_roleSystemActionRights", typeof(SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection)); + _alwaysFetchRoleSystemActionRights = info.GetBoolean("_alwaysFetchRoleSystemActionRights"); + _alreadyFetchedRoleSystemActionRights = info.GetBoolean("_alreadyFetchedRoleSystemActionRights"); + _roleUser = (SD.HnD.DAL.CollectionClasses.RoleUserCollection)info.GetValue("_roleUser", typeof(SD.HnD.DAL.CollectionClasses.RoleUserCollection)); + _alwaysFetchRoleUser = info.GetBoolean("_alwaysFetchRoleUser"); + _alreadyFetchedRoleUser = info.GetBoolean("_alreadyFetchedRoleUser"); + _systemDataAnonymousRole = (SD.HnD.DAL.CollectionClasses.SystemDataCollection)info.GetValue("_systemDataAnonymousRole", typeof(SD.HnD.DAL.CollectionClasses.SystemDataCollection)); + _alwaysFetchSystemDataAnonymousRole = info.GetBoolean("_alwaysFetchSystemDataAnonymousRole"); + _alreadyFetchedSystemDataAnonymousRole = info.GetBoolean("_alreadyFetchedSystemDataAnonymousRole"); + _systemDataDefaultRoleNewUser = (SD.HnD.DAL.CollectionClasses.SystemDataCollection)info.GetValue("_systemDataDefaultRoleNewUser", typeof(SD.HnD.DAL.CollectionClasses.SystemDataCollection)); + _alwaysFetchSystemDataDefaultRoleNewUser = info.GetBoolean("_alwaysFetchSystemDataDefaultRoleNewUser"); + _alreadyFetchedSystemDataDefaultRoleNewUser = info.GetBoolean("_alreadyFetchedSystemDataDefaultRoleNewUser"); + _assignedSystemActionRights = (SD.HnD.DAL.CollectionClasses.ActionRightCollection)info.GetValue("_assignedSystemActionRights", typeof(SD.HnD.DAL.CollectionClasses.ActionRightCollection)); + _alwaysFetchAssignedSystemActionRights = info.GetBoolean("_alwaysFetchAssignedSystemActionRights"); + _alreadyFetchedAssignedSystemActionRights = info.GetBoolean("_alreadyFetchedAssignedSystemActionRights"); + _assignedAuditActions = (SD.HnD.DAL.CollectionClasses.AuditActionCollection)info.GetValue("_assignedAuditActions", typeof(SD.HnD.DAL.CollectionClasses.AuditActionCollection)); + _alwaysFetchAssignedAuditActions = info.GetBoolean("_alwaysFetchAssignedAuditActions"); + _alreadyFetchedAssignedAuditActions = info.GetBoolean("_alreadyFetchedAssignedAuditActions"); + _users = (SD.HnD.DAL.CollectionClasses.UserCollection)info.GetValue("_users", typeof(SD.HnD.DAL.CollectionClasses.UserCollection)); + _alwaysFetchUsers = info.GetBoolean("_alwaysFetchUsers"); + _alreadyFetchedUsers = info.GetBoolean("_alreadyFetchedUsers"); + + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((RoleFieldIndex)fieldIndex) + { + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedForumRoleForumActionRights = (_forumRoleForumActionRights.Count > 0); + _alreadyFetchedRoleAuditAction = (_roleAuditAction.Count > 0); + _alreadyFetchedRoleSystemActionRights = (_roleSystemActionRights.Count > 0); + _alreadyFetchedRoleUser = (_roleUser.Count > 0); + _alreadyFetchedSystemDataAnonymousRole = (_systemDataAnonymousRole.Count > 0); + _alreadyFetchedSystemDataDefaultRoleNewUser = (_systemDataDefaultRoleNewUser.Count > 0); + _alreadyFetchedAssignedSystemActionRights = (_assignedSystemActionRights.Count > 0); + _alreadyFetchedAssignedAuditActions = (_assignedAuditActions.Count > 0); + _alreadyFetchedUsers = (_users.Count > 0); + + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return RoleEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + + case "ForumRoleForumActionRights": + toReturn.Add(RoleEntity.Relations.ForumRoleForumActionRightEntityUsingRoleID); + break; + case "RoleAuditAction": + toReturn.Add(RoleEntity.Relations.RoleAuditActionEntityUsingRoleID); + break; + case "RoleSystemActionRights": + toReturn.Add(RoleEntity.Relations.RoleSystemActionRightEntityUsingRoleID); + break; + case "RoleUser": + toReturn.Add(RoleEntity.Relations.RoleUserEntityUsingRoleID); + break; + case "SystemDataAnonymousRole": + toReturn.Add(RoleEntity.Relations.SystemDataEntityUsingAnonymousRole); + break; + case "SystemDataDefaultRoleNewUser": + toReturn.Add(RoleEntity.Relations.SystemDataEntityUsingDefaultRoleNewUser); + break; + case "AssignedSystemActionRights": + toReturn.Add(RoleEntity.Relations.RoleSystemActionRightEntityUsingRoleID, "RoleEntity__", "RoleSystemActionRight_", JoinHint.None); + toReturn.Add(RoleSystemActionRightEntity.Relations.ActionRightEntityUsingActionRightID, "RoleSystemActionRight_", string.Empty, JoinHint.None); + break; + case "AssignedAuditActions": + toReturn.Add(RoleEntity.Relations.RoleAuditActionEntityUsingRoleID, "RoleEntity__", "RoleAuditAction_", JoinHint.None); + toReturn.Add(RoleAuditActionEntity.Relations.AuditActionEntityUsingAuditActionID, "RoleAuditAction_", string.Empty, JoinHint.None); + break; + case "Users": + toReturn.Add(RoleEntity.Relations.RoleUserEntityUsingRoleID, "RoleEntity__", "RoleUser_", JoinHint.None); + toReturn.Add(RoleUserEntity.Relations.UserEntityUsingUserID, "RoleUser_", string.Empty, JoinHint.None); + break; + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_forumRoleForumActionRights", (!this.MarkedForDeletion?_forumRoleForumActionRights:null)); + info.AddValue("_alwaysFetchForumRoleForumActionRights", _alwaysFetchForumRoleForumActionRights); + info.AddValue("_alreadyFetchedForumRoleForumActionRights", _alreadyFetchedForumRoleForumActionRights); + info.AddValue("_roleAuditAction", (!this.MarkedForDeletion?_roleAuditAction:null)); + info.AddValue("_alwaysFetchRoleAuditAction", _alwaysFetchRoleAuditAction); + info.AddValue("_alreadyFetchedRoleAuditAction", _alreadyFetchedRoleAuditAction); + info.AddValue("_roleSystemActionRights", (!this.MarkedForDeletion?_roleSystemActionRights:null)); + info.AddValue("_alwaysFetchRoleSystemActionRights", _alwaysFetchRoleSystemActionRights); + info.AddValue("_alreadyFetchedRoleSystemActionRights", _alreadyFetchedRoleSystemActionRights); + info.AddValue("_roleUser", (!this.MarkedForDeletion?_roleUser:null)); + info.AddValue("_alwaysFetchRoleUser", _alwaysFetchRoleUser); + info.AddValue("_alreadyFetchedRoleUser", _alreadyFetchedRoleUser); + info.AddValue("_systemDataAnonymousRole", (!this.MarkedForDeletion?_systemDataAnonymousRole:null)); + info.AddValue("_alwaysFetchSystemDataAnonymousRole", _alwaysFetchSystemDataAnonymousRole); + info.AddValue("_alreadyFetchedSystemDataAnonymousRole", _alreadyFetchedSystemDataAnonymousRole); + info.AddValue("_systemDataDefaultRoleNewUser", (!this.MarkedForDeletion?_systemDataDefaultRoleNewUser:null)); + info.AddValue("_alwaysFetchSystemDataDefaultRoleNewUser", _alwaysFetchSystemDataDefaultRoleNewUser); + info.AddValue("_alreadyFetchedSystemDataDefaultRoleNewUser", _alreadyFetchedSystemDataDefaultRoleNewUser); + info.AddValue("_assignedSystemActionRights", (!this.MarkedForDeletion?_assignedSystemActionRights:null)); + info.AddValue("_alwaysFetchAssignedSystemActionRights", _alwaysFetchAssignedSystemActionRights); + info.AddValue("_alreadyFetchedAssignedSystemActionRights", _alreadyFetchedAssignedSystemActionRights); + info.AddValue("_assignedAuditActions", (!this.MarkedForDeletion?_assignedAuditActions:null)); + info.AddValue("_alwaysFetchAssignedAuditActions", _alwaysFetchAssignedAuditActions); + info.AddValue("_alreadyFetchedAssignedAuditActions", _alreadyFetchedAssignedAuditActions); + info.AddValue("_users", (!this.MarkedForDeletion?_users:null)); + info.AddValue("_alwaysFetchUsers", _alwaysFetchUsers); + info.AddValue("_alreadyFetchedUsers", _alreadyFetchedUsers); + + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + + case "ForumRoleForumActionRights": + _alreadyFetchedForumRoleForumActionRights = true; + if(entity!=null) + { + this.ForumRoleForumActionRights.Add((ForumRoleForumActionRightEntity)entity); + } + break; + case "RoleAuditAction": + _alreadyFetchedRoleAuditAction = true; + if(entity!=null) + { + this.RoleAuditAction.Add((RoleAuditActionEntity)entity); + } + break; + case "RoleSystemActionRights": + _alreadyFetchedRoleSystemActionRights = true; + if(entity!=null) + { + this.RoleSystemActionRights.Add((RoleSystemActionRightEntity)entity); + } + break; + case "RoleUser": + _alreadyFetchedRoleUser = true; + if(entity!=null) + { + this.RoleUser.Add((RoleUserEntity)entity); + } + break; + case "SystemDataAnonymousRole": + _alreadyFetchedSystemDataAnonymousRole = true; + if(entity!=null) + { + this.SystemDataAnonymousRole.Add((SystemDataEntity)entity); + } + break; + case "SystemDataDefaultRoleNewUser": + _alreadyFetchedSystemDataDefaultRoleNewUser = true; + if(entity!=null) + { + this.SystemDataDefaultRoleNewUser.Add((SystemDataEntity)entity); + } + break; + case "AssignedSystemActionRights": + _alreadyFetchedAssignedSystemActionRights = true; + if(entity!=null) + { + this.AssignedSystemActionRights.Add((ActionRightEntity)entity); + } + break; + case "AssignedAuditActions": + _alreadyFetchedAssignedAuditActions = true; + if(entity!=null) + { + this.AssignedAuditActions.Add((AuditActionEntity)entity); + } + break; + case "Users": + _alreadyFetchedUsers = true; + if(entity!=null) + { + this.Users.Add((UserEntity)entity); + } + break; + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + + case "ForumRoleForumActionRights": + _forumRoleForumActionRights.Add((ForumRoleForumActionRightEntity)relatedEntity); + break; + case "RoleAuditAction": + _roleAuditAction.Add((RoleAuditActionEntity)relatedEntity); + break; + case "RoleSystemActionRights": + _roleSystemActionRights.Add((RoleSystemActionRightEntity)relatedEntity); + break; + case "RoleUser": + _roleUser.Add((RoleUserEntity)relatedEntity); + break; + case "SystemDataAnonymousRole": + _systemDataAnonymousRole.Add((SystemDataEntity)relatedEntity); + break; + case "SystemDataDefaultRoleNewUser": + _systemDataDefaultRoleNewUser.Add((SystemDataEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + + case "ForumRoleForumActionRights": + base.PerformRelatedEntityRemoval(_forumRoleForumActionRights, relatedEntity, signalRelatedEntityManyToOne); + break; + case "RoleAuditAction": + base.PerformRelatedEntityRemoval(_roleAuditAction, relatedEntity, signalRelatedEntityManyToOne); + break; + case "RoleSystemActionRights": + base.PerformRelatedEntityRemoval(_roleSystemActionRights, relatedEntity, signalRelatedEntityManyToOne); + break; + case "RoleUser": + base.PerformRelatedEntityRemoval(_roleUser, relatedEntity, signalRelatedEntityManyToOne); + break; + case "SystemDataAnonymousRole": + base.PerformRelatedEntityRemoval(_systemDataAnonymousRole, relatedEntity, signalRelatedEntityManyToOne); + break; + case "SystemDataDefaultRoleNewUser": + base.PerformRelatedEntityRemoval(_systemDataDefaultRoleNewUser, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_forumRoleForumActionRights); + toReturn.Add(_roleAuditAction); + toReturn.Add(_roleSystemActionRights); + toReturn.Add(_roleUser); + toReturn.Add(_systemDataAnonymousRole); + toReturn.Add(_systemDataDefaultRoleNewUser); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Role which data should be fetched into this Role object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID) + { + return FetchUsingPK(roleID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Role which data should be fetched into this Role object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(roleID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Role which data should be fetched into this Role object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(roleID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Role which data should be fetched into this Role object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(roleID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.RoleID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(RoleFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(RoleFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new RoleRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ForumRoleForumActionRightEntity' + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch) + { + return GetMultiForumRoleForumActionRights(forceFetch, _forumRoleForumActionRights.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ForumRoleForumActionRightEntity' + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IPredicateExpression filter) + { + return GetMultiForumRoleForumActionRights(forceFetch, _forumRoleForumActionRights.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiForumRoleForumActionRights(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection GetMultiForumRoleForumActionRights(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedForumRoleForumActionRights || forceFetch || _alwaysFetchForumRoleForumActionRights) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_forumRoleForumActionRights.ParticipatesInTransaction) + { + base.Transaction.Add(_forumRoleForumActionRights); + } + } + _forumRoleForumActionRights.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _forumRoleForumActionRights.EntityFactoryToUse = entityFactoryToUse; + } + _forumRoleForumActionRights.GetMultiManyToOne(null, null, this, filter); + _forumRoleForumActionRights.SuppressClearInGetMulti=false; + _alreadyFetchedForumRoleForumActionRights = true; + } + return _forumRoleForumActionRights; + } + + /// Sets the collection parameters for the collection for 'ForumRoleForumActionRights'. These settings will be taken into account + /// when the property ForumRoleForumActionRights is requested or GetMultiForumRoleForumActionRights is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersForumRoleForumActionRights(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _forumRoleForumActionRights.SortClauses=sortClauses; + _forumRoleForumActionRights.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleAuditActionEntity' + public SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection GetMultiRoleAuditAction(bool forceFetch) + { + return GetMultiRoleAuditAction(forceFetch, _roleAuditAction.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'RoleAuditActionEntity' + public SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection GetMultiRoleAuditAction(bool forceFetch, IPredicateExpression filter) + { + return GetMultiRoleAuditAction(forceFetch, _roleAuditAction.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection GetMultiRoleAuditAction(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiRoleAuditAction(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection GetMultiRoleAuditAction(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedRoleAuditAction || forceFetch || _alwaysFetchRoleAuditAction) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_roleAuditAction.ParticipatesInTransaction) + { + base.Transaction.Add(_roleAuditAction); + } + } + _roleAuditAction.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _roleAuditAction.EntityFactoryToUse = entityFactoryToUse; + } + _roleAuditAction.GetMultiManyToOne(null, this, filter); + _roleAuditAction.SuppressClearInGetMulti=false; + _alreadyFetchedRoleAuditAction = true; + } + return _roleAuditAction; + } + + /// Sets the collection parameters for the collection for 'RoleAuditAction'. These settings will be taken into account + /// when the property RoleAuditAction is requested or GetMultiRoleAuditAction is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersRoleAuditAction(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _roleAuditAction.SortClauses=sortClauses; + _roleAuditAction.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleSystemActionRightEntity' + public SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection GetMultiRoleSystemActionRights(bool forceFetch) + { + return GetMultiRoleSystemActionRights(forceFetch, _roleSystemActionRights.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'RoleSystemActionRightEntity' + public SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection GetMultiRoleSystemActionRights(bool forceFetch, IPredicateExpression filter) + { + return GetMultiRoleSystemActionRights(forceFetch, _roleSystemActionRights.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection GetMultiRoleSystemActionRights(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiRoleSystemActionRights(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection GetMultiRoleSystemActionRights(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedRoleSystemActionRights || forceFetch || _alwaysFetchRoleSystemActionRights) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_roleSystemActionRights.ParticipatesInTransaction) + { + base.Transaction.Add(_roleSystemActionRights); + } + } + _roleSystemActionRights.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _roleSystemActionRights.EntityFactoryToUse = entityFactoryToUse; + } + _roleSystemActionRights.GetMultiManyToOne(null, this, filter); + _roleSystemActionRights.SuppressClearInGetMulti=false; + _alreadyFetchedRoleSystemActionRights = true; + } + return _roleSystemActionRights; + } + + /// Sets the collection parameters for the collection for 'RoleSystemActionRights'. These settings will be taken into account + /// when the property RoleSystemActionRights is requested or GetMultiRoleSystemActionRights is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersRoleSystemActionRights(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _roleSystemActionRights.SortClauses=sortClauses; + _roleSystemActionRights.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleUserEntity' + public SD.HnD.DAL.CollectionClasses.RoleUserCollection GetMultiRoleUser(bool forceFetch) + { + return GetMultiRoleUser(forceFetch, _roleUser.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'RoleUserEntity' + public SD.HnD.DAL.CollectionClasses.RoleUserCollection GetMultiRoleUser(bool forceFetch, IPredicateExpression filter) + { + return GetMultiRoleUser(forceFetch, _roleUser.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleUserCollection GetMultiRoleUser(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiRoleUser(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.RoleUserCollection GetMultiRoleUser(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedRoleUser || forceFetch || _alwaysFetchRoleUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_roleUser.ParticipatesInTransaction) + { + base.Transaction.Add(_roleUser); + } + } + _roleUser.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _roleUser.EntityFactoryToUse = entityFactoryToUse; + } + _roleUser.GetMultiManyToOne(this, null, filter); + _roleUser.SuppressClearInGetMulti=false; + _alreadyFetchedRoleUser = true; + } + return _roleUser; + } + + /// Sets the collection parameters for the collection for 'RoleUser'. These settings will be taken into account + /// when the property RoleUser is requested or GetMultiRoleUser is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersRoleUser(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _roleUser.SortClauses=sortClauses; + _roleUser.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'SystemDataEntity' + public SD.HnD.DAL.CollectionClasses.SystemDataCollection GetMultiSystemDataAnonymousRole(bool forceFetch) + { + return GetMultiSystemDataAnonymousRole(forceFetch, _systemDataAnonymousRole.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'SystemDataEntity' + public SD.HnD.DAL.CollectionClasses.SystemDataCollection GetMultiSystemDataAnonymousRole(bool forceFetch, IPredicateExpression filter) + { + return GetMultiSystemDataAnonymousRole(forceFetch, _systemDataAnonymousRole.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.SystemDataCollection GetMultiSystemDataAnonymousRole(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiSystemDataAnonymousRole(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.SystemDataCollection GetMultiSystemDataAnonymousRole(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedSystemDataAnonymousRole || forceFetch || _alwaysFetchSystemDataAnonymousRole) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_systemDataAnonymousRole.ParticipatesInTransaction) + { + base.Transaction.Add(_systemDataAnonymousRole); + } + } + _systemDataAnonymousRole.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _systemDataAnonymousRole.EntityFactoryToUse = entityFactoryToUse; + } + _systemDataAnonymousRole.GetMultiManyToOne(this, null, filter); + _systemDataAnonymousRole.SuppressClearInGetMulti=false; + _alreadyFetchedSystemDataAnonymousRole = true; + } + return _systemDataAnonymousRole; + } + + /// Sets the collection parameters for the collection for 'SystemDataAnonymousRole'. These settings will be taken into account + /// when the property SystemDataAnonymousRole is requested or GetMultiSystemDataAnonymousRole is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersSystemDataAnonymousRole(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _systemDataAnonymousRole.SortClauses=sortClauses; + _systemDataAnonymousRole.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'SystemDataEntity' + public SD.HnD.DAL.CollectionClasses.SystemDataCollection GetMultiSystemDataDefaultRoleNewUser(bool forceFetch) + { + return GetMultiSystemDataDefaultRoleNewUser(forceFetch, _systemDataDefaultRoleNewUser.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'SystemDataEntity' + public SD.HnD.DAL.CollectionClasses.SystemDataCollection GetMultiSystemDataDefaultRoleNewUser(bool forceFetch, IPredicateExpression filter) + { + return GetMultiSystemDataDefaultRoleNewUser(forceFetch, _systemDataDefaultRoleNewUser.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.SystemDataCollection GetMultiSystemDataDefaultRoleNewUser(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiSystemDataDefaultRoleNewUser(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.SystemDataCollection GetMultiSystemDataDefaultRoleNewUser(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedSystemDataDefaultRoleNewUser || forceFetch || _alwaysFetchSystemDataDefaultRoleNewUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_systemDataDefaultRoleNewUser.ParticipatesInTransaction) + { + base.Transaction.Add(_systemDataDefaultRoleNewUser); + } + } + _systemDataDefaultRoleNewUser.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _systemDataDefaultRoleNewUser.EntityFactoryToUse = entityFactoryToUse; + } + _systemDataDefaultRoleNewUser.GetMultiManyToOne(null, this, filter); + _systemDataDefaultRoleNewUser.SuppressClearInGetMulti=false; + _alreadyFetchedSystemDataDefaultRoleNewUser = true; + } + return _systemDataDefaultRoleNewUser; + } + + /// Sets the collection parameters for the collection for 'SystemDataDefaultRoleNewUser'. These settings will be taken into account + /// when the property SystemDataDefaultRoleNewUser is requested or GetMultiSystemDataDefaultRoleNewUser is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersSystemDataDefaultRoleNewUser(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _systemDataDefaultRoleNewUser.SortClauses=sortClauses; + _systemDataDefaultRoleNewUser.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ActionRightEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ActionRightEntity' + public SD.HnD.DAL.CollectionClasses.ActionRightCollection GetMultiAssignedSystemActionRights(bool forceFetch) + { + return GetMultiAssignedSystemActionRights(forceFetch, _assignedSystemActionRights.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'ActionRightEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ActionRightCollection GetMultiAssignedSystemActionRights(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedAssignedSystemActionRights || forceFetch || _alwaysFetchAssignedSystemActionRights) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_assignedSystemActionRights.ParticipatesInTransaction) + { + base.Transaction.Add(_assignedSystemActionRights); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(RoleFields.RoleID, ComparisonOperator.Equal, this.RoleID, "RoleEntity__")); + _assignedSystemActionRights.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _assignedSystemActionRights.EntityFactoryToUse = entityFactoryToUse; + } + _assignedSystemActionRights.GetMulti(filter, GetRelationsForField("AssignedSystemActionRights")); + _assignedSystemActionRights.SuppressClearInGetMulti=false; + _alreadyFetchedAssignedSystemActionRights = true; + } + return _assignedSystemActionRights; + } + + /// Sets the collection parameters for the collection for 'AssignedSystemActionRights'. These settings will be taken into account + /// when the property AssignedSystemActionRights is requested or GetMultiAssignedSystemActionRights is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersAssignedSystemActionRights(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _assignedSystemActionRights.SortClauses=sortClauses; + _assignedSystemActionRights.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'AuditActionEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'AuditActionEntity' + public SD.HnD.DAL.CollectionClasses.AuditActionCollection GetMultiAssignedAuditActions(bool forceFetch) + { + return GetMultiAssignedAuditActions(forceFetch, _assignedAuditActions.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'AuditActionEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.AuditActionCollection GetMultiAssignedAuditActions(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedAssignedAuditActions || forceFetch || _alwaysFetchAssignedAuditActions) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_assignedAuditActions.ParticipatesInTransaction) + { + base.Transaction.Add(_assignedAuditActions); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(RoleFields.RoleID, ComparisonOperator.Equal, this.RoleID, "RoleEntity__")); + _assignedAuditActions.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _assignedAuditActions.EntityFactoryToUse = entityFactoryToUse; + } + _assignedAuditActions.GetMulti(filter, GetRelationsForField("AssignedAuditActions")); + _assignedAuditActions.SuppressClearInGetMulti=false; + _alreadyFetchedAssignedAuditActions = true; + } + return _assignedAuditActions; + } + + /// Sets the collection parameters for the collection for 'AssignedAuditActions'. These settings will be taken into account + /// when the property AssignedAuditActions is requested or GetMultiAssignedAuditActions is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersAssignedAuditActions(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _assignedAuditActions.SortClauses=sortClauses; + _assignedAuditActions.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'UserEntity' + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsers(bool forceFetch) + { + return GetMultiUsers(forceFetch, _users.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsers(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedUsers || forceFetch || _alwaysFetchUsers) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_users.ParticipatesInTransaction) + { + base.Transaction.Add(_users); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(RoleFields.RoleID, ComparisonOperator.Equal, this.RoleID, "RoleEntity__")); + _users.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _users.EntityFactoryToUse = entityFactoryToUse; + } + _users.GetMulti(filter, GetRelationsForField("Users")); + _users.SuppressClearInGetMulti=false; + _alreadyFetchedUsers = true; + } + return _users; + } + + /// Sets the collection parameters for the collection for 'Users'. These settings will be taken into account + /// when the property Users is requested or GetMultiUsers is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersUsers(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _users.SortClauses=sortClauses; + _users.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + RoleDAO dao = (RoleDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _forumRoleForumActionRights.ActiveContext = base.ActiveContext; + _roleAuditAction.ActiveContext = base.ActiveContext; + _roleSystemActionRights.ActiveContext = base.ActiveContext; + _roleUser.ActiveContext = base.ActiveContext; + _systemDataAnonymousRole.ActiveContext = base.ActiveContext; + _systemDataDefaultRoleNewUser.ActiveContext = base.ActiveContext; + _assignedSystemActionRights.ActiveContext = base.ActiveContext; + _assignedAuditActions.ActiveContext = base.ActiveContext; + _users.ActiveContext = base.ActiveContext; + + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + RoleDAO dao = (RoleDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + RoleDAO dao = (RoleDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + + toReturn.Add("ForumRoleForumActionRights", _forumRoleForumActionRights); + toReturn.Add("RoleAuditAction", _roleAuditAction); + toReturn.Add("RoleSystemActionRights", _roleSystemActionRights); + toReturn.Add("RoleUser", _roleUser); + toReturn.Add("SystemDataAnonymousRole", _systemDataAnonymousRole); + toReturn.Add("SystemDataDefaultRoleNewUser", _systemDataDefaultRoleNewUser); + toReturn.Add("AssignedSystemActionRights", _assignedSystemActionRights); + toReturn.Add("AssignedAuditActions", _assignedAuditActions); + toReturn.Add("Users", _users); + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for Role which data should be fetched into this Role object + /// The validator object for this RoleEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 roleID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(roleID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _forumRoleForumActionRights = new SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection(new ForumRoleForumActionRightEntityFactory()); + _forumRoleForumActionRights.SetContainingEntityInfo(this, "Role"); + _alwaysFetchForumRoleForumActionRights = false; + _alreadyFetchedForumRoleForumActionRights = false; + _roleAuditAction = new SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection(new RoleAuditActionEntityFactory()); + _roleAuditAction.SetContainingEntityInfo(this, "Role"); + _alwaysFetchRoleAuditAction = false; + _alreadyFetchedRoleAuditAction = false; + _roleSystemActionRights = new SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection(new RoleSystemActionRightEntityFactory()); + _roleSystemActionRights.SetContainingEntityInfo(this, "Role"); + _alwaysFetchRoleSystemActionRights = false; + _alreadyFetchedRoleSystemActionRights = false; + _roleUser = new SD.HnD.DAL.CollectionClasses.RoleUserCollection(new RoleUserEntityFactory()); + _roleUser.SetContainingEntityInfo(this, "Role"); + _alwaysFetchRoleUser = false; + _alreadyFetchedRoleUser = false; + _systemDataAnonymousRole = new SD.HnD.DAL.CollectionClasses.SystemDataCollection(new SystemDataEntityFactory()); + _systemDataAnonymousRole.SetContainingEntityInfo(this, "RoleForAnonymous"); + _alwaysFetchSystemDataAnonymousRole = false; + _alreadyFetchedSystemDataAnonymousRole = false; + _systemDataDefaultRoleNewUser = new SD.HnD.DAL.CollectionClasses.SystemDataCollection(new SystemDataEntityFactory()); + _systemDataDefaultRoleNewUser.SetContainingEntityInfo(this, "RoleForNewUser"); + _alwaysFetchSystemDataDefaultRoleNewUser = false; + _alreadyFetchedSystemDataDefaultRoleNewUser = false; + _assignedSystemActionRights = new SD.HnD.DAL.CollectionClasses.ActionRightCollection(new ActionRightEntityFactory()); + _alwaysFetchAssignedSystemActionRights = false; + _alreadyFetchedAssignedSystemActionRights = false; + _assignedAuditActions = new SD.HnD.DAL.CollectionClasses.AuditActionCollection(new AuditActionEntityFactory()); + _alwaysFetchAssignedAuditActions = false; + _alreadyFetchedAssignedAuditActions = false; + _users = new SD.HnD.DAL.CollectionClasses.UserCollection(new UserEntityFactory()); + _alwaysFetchUsers = false; + _alreadyFetchedUsers = false; + + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("RoleID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("RoleDescription", fieldHashtable); + } + #endregion + + + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for Role which data should be fetched into this Role object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 roleID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)RoleFieldIndex.RoleID].ForcedCurrentValueWrite(roleID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateRoleDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new RoleEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static RoleRelations Relations + { + get { return new RoleRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'ForumRoleForumActionRight' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathForumRoleForumActionRights + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection(), + (IEntityRelation)GetRelationsForField("ForumRoleForumActionRights")[0], (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity, 0, null, null, null, "ForumRoleForumActionRights", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'RoleAuditAction' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoleAuditAction + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection(), + (IEntityRelation)GetRelationsForField("RoleAuditAction")[0], (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.RoleAuditActionEntity, 0, null, null, null, "RoleAuditAction", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'RoleSystemActionRight' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoleSystemActionRights + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection(), + (IEntityRelation)GetRelationsForField("RoleSystemActionRights")[0], (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.RoleSystemActionRightEntity, 0, null, null, null, "RoleSystemActionRights", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'RoleUser' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoleUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleUserCollection(), + (IEntityRelation)GetRelationsForField("RoleUser")[0], (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.RoleUserEntity, 0, null, null, null, "RoleUser", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'SystemData' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSystemDataAnonymousRole + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SystemDataCollection(), + (IEntityRelation)GetRelationsForField("SystemDataAnonymousRole")[0], (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.SystemDataEntity, 0, null, null, null, "SystemDataAnonymousRole", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'SystemData' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSystemDataDefaultRoleNewUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SystemDataCollection(), + (IEntityRelation)GetRelationsForField("SystemDataDefaultRoleNewUser")[0], (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.SystemDataEntity, 0, null, null, null, "SystemDataDefaultRoleNewUser", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'ActionRight' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathAssignedSystemActionRights + { + get + { + IEntityRelation intermediateRelation = RoleEntity.Relations.RoleSystemActionRightEntityUsingRoleID; + intermediateRelation.SetAliases(string.Empty, "RoleSystemActionRight_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ActionRightCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.ActionRightEntity, 0, null, null, GetRelationsForField("AssignedSystemActionRights"), "AssignedSystemActionRights", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'AuditAction' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathAssignedAuditActions + { + get + { + IEntityRelation intermediateRelation = RoleEntity.Relations.RoleAuditActionEntityUsingRoleID; + intermediateRelation.SetAliases(string.Empty, "RoleAuditAction_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.AuditActionCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.AuditActionEntity, 0, null, null, GetRelationsForField("AssignedAuditActions"), "AssignedAuditActions", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUsers + { + get + { + IEntityRelation intermediateRelation = RoleEntity.Relations.RoleUserEntityUsingRoleID; + intermediateRelation.SetAliases(string.Empty, "RoleUser_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.RoleEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, GetRelationsForField("Users"), "Users", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "RoleEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return RoleEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return RoleEntity.FieldsCustomProperties;} + } + + /// The RoleID property of the Entity Role

+ ///
+ /// Mapped on table field: "Role"."RoleID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 RoleID + { + get { return (System.Int32)GetValue((int)RoleFieldIndex.RoleID, true); } + set { SetValue((int)RoleFieldIndex.RoleID, value, true); } + } + /// The RoleDescription property of the Entity Role

+ ///
+ /// Mapped on table field: "Role"."RoleDescription"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 50
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String RoleDescription + { + get { return (System.String)GetValue((int)RoleFieldIndex.RoleDescription, true); } + set { SetValue((int)RoleFieldIndex.RoleDescription, value, true); } + } + + /// Retrieves all related entities of type 'ForumRoleForumActionRightEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiForumRoleForumActionRights()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ForumRoleForumActionRightCollection ForumRoleForumActionRights + { + get { return GetMultiForumRoleForumActionRights(false); } + } + + /// Gets / sets the lazy loading flag for ForumRoleForumActionRights. When set to true, ForumRoleForumActionRights is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ForumRoleForumActionRights is accessed. You can always execute + /// a forced fetch by calling GetMultiForumRoleForumActionRights(true). + [Browsable(false)] + public bool AlwaysFetchForumRoleForumActionRights + { + get { return _alwaysFetchForumRoleForumActionRights; } + set { _alwaysFetchForumRoleForumActionRights = value; } + } + + /// Gets / Sets the lazy loading flag if the property ForumRoleForumActionRights already has been fetched. Setting this property to false when ForumRoleForumActionRights has been fetched + /// will clear the ForumRoleForumActionRights collection well. Setting this property to true while ForumRoleForumActionRights hasn't been fetched disables lazy loading for ForumRoleForumActionRights + [Browsable(false)] + public bool AlreadyFetchedForumRoleForumActionRights + { + get { return _alreadyFetchedForumRoleForumActionRights;} + set + { + if(_alreadyFetchedForumRoleForumActionRights && !value && (_forumRoleForumActionRights != null)) + { + _forumRoleForumActionRights.Clear(); + } + _alreadyFetchedForumRoleForumActionRights = value; + } + } + /// Retrieves all related entities of type 'RoleAuditActionEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiRoleAuditAction()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleAuditActionCollection RoleAuditAction + { + get { return GetMultiRoleAuditAction(false); } + } + + /// Gets / sets the lazy loading flag for RoleAuditAction. When set to true, RoleAuditAction is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RoleAuditAction is accessed. You can always execute + /// a forced fetch by calling GetMultiRoleAuditAction(true). + [Browsable(false)] + public bool AlwaysFetchRoleAuditAction + { + get { return _alwaysFetchRoleAuditAction; } + set { _alwaysFetchRoleAuditAction = value; } + } + + /// Gets / Sets the lazy loading flag if the property RoleAuditAction already has been fetched. Setting this property to false when RoleAuditAction has been fetched + /// will clear the RoleAuditAction collection well. Setting this property to true while RoleAuditAction hasn't been fetched disables lazy loading for RoleAuditAction + [Browsable(false)] + public bool AlreadyFetchedRoleAuditAction + { + get { return _alreadyFetchedRoleAuditAction;} + set + { + if(_alreadyFetchedRoleAuditAction && !value && (_roleAuditAction != null)) + { + _roleAuditAction.Clear(); + } + _alreadyFetchedRoleAuditAction = value; + } + } + /// Retrieves all related entities of type 'RoleSystemActionRightEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiRoleSystemActionRights()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleSystemActionRightCollection RoleSystemActionRights + { + get { return GetMultiRoleSystemActionRights(false); } + } + + /// Gets / sets the lazy loading flag for RoleSystemActionRights. When set to true, RoleSystemActionRights is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RoleSystemActionRights is accessed. You can always execute + /// a forced fetch by calling GetMultiRoleSystemActionRights(true). + [Browsable(false)] + public bool AlwaysFetchRoleSystemActionRights + { + get { return _alwaysFetchRoleSystemActionRights; } + set { _alwaysFetchRoleSystemActionRights = value; } + } + + /// Gets / Sets the lazy loading flag if the property RoleSystemActionRights already has been fetched. Setting this property to false when RoleSystemActionRights has been fetched + /// will clear the RoleSystemActionRights collection well. Setting this property to true while RoleSystemActionRights hasn't been fetched disables lazy loading for RoleSystemActionRights + [Browsable(false)] + public bool AlreadyFetchedRoleSystemActionRights + { + get { return _alreadyFetchedRoleSystemActionRights;} + set + { + if(_alreadyFetchedRoleSystemActionRights && !value && (_roleSystemActionRights != null)) + { + _roleSystemActionRights.Clear(); + } + _alreadyFetchedRoleSystemActionRights = value; + } + } + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiRoleUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleUserCollection RoleUser + { + get { return GetMultiRoleUser(false); } + } + + /// Gets / sets the lazy loading flag for RoleUser. When set to true, RoleUser is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RoleUser is accessed. You can always execute + /// a forced fetch by calling GetMultiRoleUser(true). + [Browsable(false)] + public bool AlwaysFetchRoleUser + { + get { return _alwaysFetchRoleUser; } + set { _alwaysFetchRoleUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property RoleUser already has been fetched. Setting this property to false when RoleUser has been fetched + /// will clear the RoleUser collection well. Setting this property to true while RoleUser hasn't been fetched disables lazy loading for RoleUser + [Browsable(false)] + public bool AlreadyFetchedRoleUser + { + get { return _alreadyFetchedRoleUser;} + set + { + if(_alreadyFetchedRoleUser && !value && (_roleUser != null)) + { + _roleUser.Clear(); + } + _alreadyFetchedRoleUser = value; + } + } + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiSystemDataAnonymousRole()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.SystemDataCollection SystemDataAnonymousRole + { + get { return GetMultiSystemDataAnonymousRole(false); } + } + + /// Gets / sets the lazy loading flag for SystemDataAnonymousRole. When set to true, SystemDataAnonymousRole is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SystemDataAnonymousRole is accessed. You can always execute + /// a forced fetch by calling GetMultiSystemDataAnonymousRole(true). + [Browsable(false)] + public bool AlwaysFetchSystemDataAnonymousRole + { + get { return _alwaysFetchSystemDataAnonymousRole; } + set { _alwaysFetchSystemDataAnonymousRole = value; } + } + + /// Gets / Sets the lazy loading flag if the property SystemDataAnonymousRole already has been fetched. Setting this property to false when SystemDataAnonymousRole has been fetched + /// will clear the SystemDataAnonymousRole collection well. Setting this property to true while SystemDataAnonymousRole hasn't been fetched disables lazy loading for SystemDataAnonymousRole + [Browsable(false)] + public bool AlreadyFetchedSystemDataAnonymousRole + { + get { return _alreadyFetchedSystemDataAnonymousRole;} + set + { + if(_alreadyFetchedSystemDataAnonymousRole && !value && (_systemDataAnonymousRole != null)) + { + _systemDataAnonymousRole.Clear(); + } + _alreadyFetchedSystemDataAnonymousRole = value; + } + } + /// Retrieves all related entities of type 'SystemDataEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiSystemDataDefaultRoleNewUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.SystemDataCollection SystemDataDefaultRoleNewUser + { + get { return GetMultiSystemDataDefaultRoleNewUser(false); } + } + + /// Gets / sets the lazy loading flag for SystemDataDefaultRoleNewUser. When set to true, SystemDataDefaultRoleNewUser is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SystemDataDefaultRoleNewUser is accessed. You can always execute + /// a forced fetch by calling GetMultiSystemDataDefaultRoleNewUser(true). + [Browsable(false)] + public bool AlwaysFetchSystemDataDefaultRoleNewUser + { + get { return _alwaysFetchSystemDataDefaultRoleNewUser; } + set { _alwaysFetchSystemDataDefaultRoleNewUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property SystemDataDefaultRoleNewUser already has been fetched. Setting this property to false when SystemDataDefaultRoleNewUser has been fetched + /// will clear the SystemDataDefaultRoleNewUser collection well. Setting this property to true while SystemDataDefaultRoleNewUser hasn't been fetched disables lazy loading for SystemDataDefaultRoleNewUser + [Browsable(false)] + public bool AlreadyFetchedSystemDataDefaultRoleNewUser + { + get { return _alreadyFetchedSystemDataDefaultRoleNewUser;} + set + { + if(_alreadyFetchedSystemDataDefaultRoleNewUser && !value && (_systemDataDefaultRoleNewUser != null)) + { + _systemDataDefaultRoleNewUser.Clear(); + } + _alreadyFetchedSystemDataDefaultRoleNewUser = value; + } + } + + /// Retrieves all related entities of type 'ActionRightEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiAssignedSystemActionRights()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ActionRightCollection AssignedSystemActionRights + { + get { return GetMultiAssignedSystemActionRights(false); } + } + + /// Gets / sets the lazy loading flag for AssignedSystemActionRights. When set to true, AssignedSystemActionRights is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time AssignedSystemActionRights is accessed. You can always execute + /// a forced fetch by calling GetMultiAssignedSystemActionRights(true). + [Browsable(false)] + public bool AlwaysFetchAssignedSystemActionRights + { + get { return _alwaysFetchAssignedSystemActionRights; } + set { _alwaysFetchAssignedSystemActionRights = value; } + } + + /// Gets / Sets the lazy loading flag if the property AssignedSystemActionRights already has been fetched. Setting this property to false when AssignedSystemActionRights has been fetched + /// will clear the AssignedSystemActionRights collection well. Setting this property to true while AssignedSystemActionRights hasn't been fetched disables lazy loading for AssignedSystemActionRights + [Browsable(false)] + public bool AlreadyFetchedAssignedSystemActionRights + { + get { return _alreadyFetchedAssignedSystemActionRights;} + set + { + if(_alreadyFetchedAssignedSystemActionRights && !value && (_assignedSystemActionRights != null)) + { + _assignedSystemActionRights.Clear(); + } + _alreadyFetchedAssignedSystemActionRights = value; + } + } + /// Retrieves all related entities of type 'AuditActionEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiAssignedAuditActions()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.AuditActionCollection AssignedAuditActions + { + get { return GetMultiAssignedAuditActions(false); } + } + + /// Gets / sets the lazy loading flag for AssignedAuditActions. When set to true, AssignedAuditActions is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time AssignedAuditActions is accessed. You can always execute + /// a forced fetch by calling GetMultiAssignedAuditActions(true). + [Browsable(false)] + public bool AlwaysFetchAssignedAuditActions + { + get { return _alwaysFetchAssignedAuditActions; } + set { _alwaysFetchAssignedAuditActions = value; } + } + + /// Gets / Sets the lazy loading flag if the property AssignedAuditActions already has been fetched. Setting this property to false when AssignedAuditActions has been fetched + /// will clear the AssignedAuditActions collection well. Setting this property to true while AssignedAuditActions hasn't been fetched disables lazy loading for AssignedAuditActions + [Browsable(false)] + public bool AlreadyFetchedAssignedAuditActions + { + get { return _alreadyFetchedAssignedAuditActions;} + set + { + if(_alreadyFetchedAssignedAuditActions && !value && (_assignedAuditActions != null)) + { + _assignedAuditActions.Clear(); + } + _alreadyFetchedAssignedAuditActions = value; + } + } + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiUsers()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.UserCollection Users + { + get { return GetMultiUsers(false); } + } + + /// Gets / sets the lazy loading flag for Users. When set to true, Users is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Users is accessed. You can always execute + /// a forced fetch by calling GetMultiUsers(true). + [Browsable(false)] + public bool AlwaysFetchUsers + { + get { return _alwaysFetchUsers; } + set { _alwaysFetchUsers = value; } + } + + /// Gets / Sets the lazy loading flag if the property Users already has been fetched. Setting this property to false when Users has been fetched + /// will clear the Users collection well. Setting this property to true while Users hasn't been fetched disables lazy loading for Users + [Browsable(false)] + public bool AlreadyFetchedUsers + { + get { return _alreadyFetchedUsers;} + set + { + if(_alreadyFetchedUsers && !value && (_users != null)) + { + _users.Clear(); + } + _alreadyFetchedUsers = value; + } + } + + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.RoleEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/RoleSystemActionRightEntityBase.cs b/DAL/EntityBaseClasses/RoleSystemActionRightEntityBase.cs new file mode 100644 index 0000000..eeace97 --- /dev/null +++ b/DAL/EntityBaseClasses/RoleSystemActionRightEntityBase.cs @@ -0,0 +1,1089 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'RoleSystemActionRight'.

+ /// + ///
+ [Serializable] + public abstract partial class RoleSystemActionRightEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private ActionRightEntity _actionRight; + private bool _alwaysFetchActionRight, _alreadyFetchedActionRight, _actionRightReturnsNewIfNotFound; + private RoleEntity _role; + private bool _alwaysFetchRole, _alreadyFetchedRole, _roleReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name ActionRight + public static readonly string ActionRight = "ActionRight"; + /// Member name Role + public static readonly string Role = "Role"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static RoleSystemActionRightEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public RoleSystemActionRightEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + public RoleSystemActionRightEntityBase(System.Int32 roleID, System.Int32 actionRightID) + { + InitClassFetch(roleID, actionRightID, null, null); + } + + /// CTor + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + public RoleSystemActionRightEntityBase(System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(roleID, actionRightID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// The custom validator object for this RoleSystemActionRightEntity + public RoleSystemActionRightEntityBase(System.Int32 roleID, System.Int32 actionRightID, IValidator validator) + { + InitClassFetch(roleID, actionRightID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected RoleSystemActionRightEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _actionRight = (ActionRightEntity)info.GetValue("_actionRight", typeof(ActionRightEntity)); + if(_actionRight!=null) + { + _actionRight.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _actionRightReturnsNewIfNotFound = info.GetBoolean("_actionRightReturnsNewIfNotFound"); + _alwaysFetchActionRight = info.GetBoolean("_alwaysFetchActionRight"); + _alreadyFetchedActionRight = info.GetBoolean("_alreadyFetchedActionRight"); + _role = (RoleEntity)info.GetValue("_role", typeof(RoleEntity)); + if(_role!=null) + { + _role.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _roleReturnsNewIfNotFound = info.GetBoolean("_roleReturnsNewIfNotFound"); + _alwaysFetchRole = info.GetBoolean("_alwaysFetchRole"); + _alreadyFetchedRole = info.GetBoolean("_alreadyFetchedRole"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((RoleSystemActionRightFieldIndex)fieldIndex) + { + case RoleSystemActionRightFieldIndex.RoleID: + DesetupSyncRole(true, false); + _alreadyFetchedRole = false; + break; + case RoleSystemActionRightFieldIndex.ActionRightID: + DesetupSyncActionRight(true, false); + _alreadyFetchedActionRight = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedActionRight = (_actionRight != null); + _alreadyFetchedRole = (_role != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return RoleSystemActionRightEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "ActionRight": + toReturn.Add(RoleSystemActionRightEntity.Relations.ActionRightEntityUsingActionRightID); + break; + case "Role": + toReturn.Add(RoleSystemActionRightEntity.Relations.RoleEntityUsingRoleID); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_actionRight", (!this.MarkedForDeletion?_actionRight:null)); + info.AddValue("_actionRightReturnsNewIfNotFound", _actionRightReturnsNewIfNotFound); + info.AddValue("_alwaysFetchActionRight", _alwaysFetchActionRight); + info.AddValue("_alreadyFetchedActionRight", _alreadyFetchedActionRight); + info.AddValue("_role", (!this.MarkedForDeletion?_role:null)); + info.AddValue("_roleReturnsNewIfNotFound", _roleReturnsNewIfNotFound); + info.AddValue("_alwaysFetchRole", _alwaysFetchRole); + info.AddValue("_alreadyFetchedRole", _alreadyFetchedRole); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "ActionRight": + _alreadyFetchedActionRight = true; + this.ActionRight = (ActionRightEntity)entity; + break; + case "Role": + _alreadyFetchedRole = true; + this.Role = (RoleEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "ActionRight": + SetupSyncActionRight(relatedEntity); + break; + case "Role": + SetupSyncRole(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "ActionRight": + DesetupSyncActionRight(false, true); + break; + case "Role": + DesetupSyncRole(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_actionRight!=null) + { + toReturn.Add(_actionRight); + } + if(_role!=null) + { + toReturn.Add(_role); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, System.Int32 actionRightID) + { + return FetchUsingPK(roleID, actionRightID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(roleID, actionRightID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(roleID, actionRightID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(roleID, actionRightID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.RoleID, this.ActionRightID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(RoleSystemActionRightFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(RoleSystemActionRightFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new RoleSystemActionRightRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'ActionRightEntity', using a relation of type 'n:1' + /// A fetched entity of type 'ActionRightEntity' which is related to this entity. + public ActionRightEntity GetSingleActionRight() + { + return GetSingleActionRight(false); + } + + /// Retrieves the related entity of type 'ActionRightEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ActionRightEntity' which is related to this entity. + public virtual ActionRightEntity GetSingleActionRight(bool forceFetch) + { + if( ( !_alreadyFetchedActionRight || forceFetch || _alwaysFetchActionRight) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(RoleSystemActionRightEntity.Relations.ActionRightEntityUsingActionRightID); + + ActionRightEntity newEntity = new ActionRightEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ActionRightID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (ActionRightEntity)base.ActiveContext.Get(newEntity); + } + this.ActionRight = newEntity; + } + else + { + if(_actionRightReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_actionRight == null))) + { + this.ActionRight = newEntity; + } + } + else + { + this.ActionRight = null; + } + } + _alreadyFetchedActionRight = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _actionRight; + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public RoleEntity GetSingleRole() + { + return GetSingleRole(false); + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public virtual RoleEntity GetSingleRole(bool forceFetch) + { + if( ( !_alreadyFetchedRole || forceFetch || _alwaysFetchRole) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(RoleSystemActionRightEntity.Relations.RoleEntityUsingRoleID); + + RoleEntity newEntity = new RoleEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.RoleID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (RoleEntity)base.ActiveContext.Get(newEntity); + } + this.Role = newEntity; + } + else + { + if(_roleReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_role == null))) + { + this.Role = newEntity; + } + } + else + { + this.Role = null; + } + } + _alreadyFetchedRole = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _role; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + RoleSystemActionRightDAO dao = (RoleSystemActionRightDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_actionRight!=null) + { + _actionRight.ActiveContext = base.ActiveContext; + } + if(_role!=null) + { + _role.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + RoleSystemActionRightDAO dao = (RoleSystemActionRightDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + RoleSystemActionRightDAO dao = (RoleSystemActionRightDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleSystemActionRightEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("ActionRight", _actionRight); + toReturn.Add("Role", _role); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// The validator object for this RoleSystemActionRightEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 roleID, System.Int32 actionRightID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(roleID, actionRightID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _actionRight = null; + _actionRightReturnsNewIfNotFound = true; + _alwaysFetchActionRight = false; + _alreadyFetchedActionRight = false; + _role = null; + _roleReturnsNewIfNotFound = true; + _alwaysFetchRole = false; + _alreadyFetchedRole = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("RoleID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ActionRightID", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _actionRight + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncActionRight(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _actionRight, new PropertyChangedEventHandler( OnActionRightPropertyChanged ), "ActionRight", RoleSystemActionRightEntity.Relations.ActionRightEntityUsingActionRightID, true, signalRelatedEntity, "RoleSystemActionRights", resetFKFields, new int[] { (int)RoleSystemActionRightFieldIndex.ActionRightID } ); + _actionRight = null; + } + + /// setups the sync logic for member _actionRight + /// Instance to set as the related entity of type entityType + private void SetupSyncActionRight(IEntity relatedEntity) + { + if(_actionRight!=relatedEntity) + { + DesetupSyncActionRight(true, true); + _actionRight = (ActionRightEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _actionRight, new PropertyChangedEventHandler( OnActionRightPropertyChanged ), "ActionRight", RoleSystemActionRightEntity.Relations.ActionRightEntityUsingActionRightID, true, ref _alreadyFetchedActionRight, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnActionRightPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _role + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncRole(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _role, new PropertyChangedEventHandler( OnRolePropertyChanged ), "Role", RoleSystemActionRightEntity.Relations.RoleEntityUsingRoleID, true, signalRelatedEntity, "RoleSystemActionRights", resetFKFields, new int[] { (int)RoleSystemActionRightFieldIndex.RoleID } ); + _role = null; + } + + /// setups the sync logic for member _role + /// Instance to set as the related entity of type entityType + private void SetupSyncRole(IEntity relatedEntity) + { + if(_role!=relatedEntity) + { + DesetupSyncRole(true, true); + _role = (RoleEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _role, new PropertyChangedEventHandler( OnRolePropertyChanged ), "Role", RoleSystemActionRightEntity.Relations.RoleEntityUsingRoleID, true, ref _alreadyFetchedRole, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnRolePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)RoleSystemActionRightFieldIndex.RoleID].ForcedCurrentValueWrite(roleID); + base.Fields[(int)RoleSystemActionRightFieldIndex.ActionRightID].ForcedCurrentValueWrite(actionRightID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateRoleSystemActionRightDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new RoleSystemActionRightEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static RoleSystemActionRightRelations Relations + { + get { return new RoleSystemActionRightRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'ActionRight' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathActionRight + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ActionRightCollection(), + (IEntityRelation)GetRelationsForField("ActionRight")[0], (int)SD.HnD.DAL.EntityType.RoleSystemActionRightEntity, (int)SD.HnD.DAL.EntityType.ActionRightEntity, 0, null, null, null, "ActionRight", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRole + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), + (IEntityRelation)GetRelationsForField("Role")[0], (int)SD.HnD.DAL.EntityType.RoleSystemActionRightEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, null, "Role", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "RoleSystemActionRightEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return RoleSystemActionRightEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return RoleSystemActionRightEntity.FieldsCustomProperties;} + } + + /// The RoleID property of the Entity RoleSystemActionRight

+ ///
+ /// Mapped on table field: "RoleSystemActionRight"."RoleID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 RoleID + { + get { return (System.Int32)GetValue((int)RoleSystemActionRightFieldIndex.RoleID, true); } + set { SetValue((int)RoleSystemActionRightFieldIndex.RoleID, value, true); } + } + /// The ActionRightID property of the Entity RoleSystemActionRight

+ ///
+ /// Mapped on table field: "RoleSystemActionRight"."ActionRightID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 ActionRightID + { + get { return (System.Int32)GetValue((int)RoleSystemActionRightFieldIndex.ActionRightID, true); } + set { SetValue((int)RoleSystemActionRightFieldIndex.ActionRightID, value, true); } + } + + + + /// Gets / sets related entity of type 'ActionRightEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleActionRight()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ActionRightEntity ActionRight + { + get { return GetSingleActionRight(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncActionRight(value); + } + else + { + if(value==null) + { + if(_actionRight != null) + { + _actionRight.UnsetRelatedEntity(this, "RoleSystemActionRights"); + } + } + else + { + if(_actionRight!=value) + { + ((IEntity)value).SetRelatedEntity(this, "RoleSystemActionRights"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for ActionRight. When set to true, ActionRight is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ActionRight is accessed. You can always execute + /// a forced fetch by calling GetSingleActionRight(true). + [Browsable(false)] + public bool AlwaysFetchActionRight + { + get { return _alwaysFetchActionRight; } + set { _alwaysFetchActionRight = value; } + } + + /// Gets / Sets the lazy loading flag if the property ActionRight already has been fetched. Setting this property to false when ActionRight has been fetched + /// will set ActionRight to null as well. Setting this property to true while ActionRight hasn't been fetched disables lazy loading for ActionRight + [Browsable(false)] + public bool AlreadyFetchedActionRight + { + get { return _alreadyFetchedActionRight;} + set + { + if(_alreadyFetchedActionRight && !value) + { + this.ActionRight = null; + } + _alreadyFetchedActionRight = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property ActionRight is not found + /// in the database. When set to true, ActionRight will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ActionRightReturnsNewIfNotFound + { + get { return _actionRightReturnsNewIfNotFound; } + set { _actionRightReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'RoleEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleRole()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual RoleEntity Role + { + get { return GetSingleRole(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncRole(value); + } + else + { + if(value==null) + { + if(_role != null) + { + _role.UnsetRelatedEntity(this, "RoleSystemActionRights"); + } + } + else + { + if(_role!=value) + { + ((IEntity)value).SetRelatedEntity(this, "RoleSystemActionRights"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Role. When set to true, Role is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Role is accessed. You can always execute + /// a forced fetch by calling GetSingleRole(true). + [Browsable(false)] + public bool AlwaysFetchRole + { + get { return _alwaysFetchRole; } + set { _alwaysFetchRole = value; } + } + + /// Gets / Sets the lazy loading flag if the property Role already has been fetched. Setting this property to false when Role has been fetched + /// will set Role to null as well. Setting this property to true while Role hasn't been fetched disables lazy loading for Role + [Browsable(false)] + public bool AlreadyFetchedRole + { + get { return _alreadyFetchedRole;} + set + { + if(_alreadyFetchedRole && !value) + { + this.Role = null; + } + _alreadyFetchedRole = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Role is not found + /// in the database. When set to true, Role will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool RoleReturnsNewIfNotFound + { + get { return _roleReturnsNewIfNotFound; } + set { _roleReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.RoleSystemActionRightEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/RoleUserEntityBase.cs b/DAL/EntityBaseClasses/RoleUserEntityBase.cs new file mode 100644 index 0000000..7d299de --- /dev/null +++ b/DAL/EntityBaseClasses/RoleUserEntityBase.cs @@ -0,0 +1,1089 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'RoleUser'.

+ /// + ///
+ [Serializable] + public abstract partial class RoleUserEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private RoleEntity _role; + private bool _alwaysFetchRole, _alreadyFetchedRole, _roleReturnsNewIfNotFound; + private UserEntity _user; + private bool _alwaysFetchUser, _alreadyFetchedUser, _userReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name Role + public static readonly string Role = "Role"; + /// Member name User + public static readonly string User = "User"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static RoleUserEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public RoleUserEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + public RoleUserEntityBase(System.Int32 roleID, System.Int32 userID) + { + InitClassFetch(roleID, userID, null, null); + } + + /// CTor + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// the PrefetchPath which defines the graph of objects to fetch as well + public RoleUserEntityBase(System.Int32 roleID, System.Int32 userID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(roleID, userID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// The custom validator object for this RoleUserEntity + public RoleUserEntityBase(System.Int32 roleID, System.Int32 userID, IValidator validator) + { + InitClassFetch(roleID, userID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected RoleUserEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _role = (RoleEntity)info.GetValue("_role", typeof(RoleEntity)); + if(_role!=null) + { + _role.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _roleReturnsNewIfNotFound = info.GetBoolean("_roleReturnsNewIfNotFound"); + _alwaysFetchRole = info.GetBoolean("_alwaysFetchRole"); + _alreadyFetchedRole = info.GetBoolean("_alreadyFetchedRole"); + _user = (UserEntity)info.GetValue("_user", typeof(UserEntity)); + if(_user!=null) + { + _user.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _userReturnsNewIfNotFound = info.GetBoolean("_userReturnsNewIfNotFound"); + _alwaysFetchUser = info.GetBoolean("_alwaysFetchUser"); + _alreadyFetchedUser = info.GetBoolean("_alreadyFetchedUser"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((RoleUserFieldIndex)fieldIndex) + { + case RoleUserFieldIndex.RoleID: + DesetupSyncRole(true, false); + _alreadyFetchedRole = false; + break; + case RoleUserFieldIndex.UserID: + DesetupSyncUser(true, false); + _alreadyFetchedUser = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedRole = (_role != null); + _alreadyFetchedUser = (_user != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return RoleUserEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "Role": + toReturn.Add(RoleUserEntity.Relations.RoleEntityUsingRoleID); + break; + case "User": + toReturn.Add(RoleUserEntity.Relations.UserEntityUsingUserID); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_role", (!this.MarkedForDeletion?_role:null)); + info.AddValue("_roleReturnsNewIfNotFound", _roleReturnsNewIfNotFound); + info.AddValue("_alwaysFetchRole", _alwaysFetchRole); + info.AddValue("_alreadyFetchedRole", _alreadyFetchedRole); + info.AddValue("_user", (!this.MarkedForDeletion?_user:null)); + info.AddValue("_userReturnsNewIfNotFound", _userReturnsNewIfNotFound); + info.AddValue("_alwaysFetchUser", _alwaysFetchUser); + info.AddValue("_alreadyFetchedUser", _alreadyFetchedUser); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "Role": + _alreadyFetchedRole = true; + this.Role = (RoleEntity)entity; + break; + case "User": + _alreadyFetchedUser = true; + this.User = (UserEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "Role": + SetupSyncRole(relatedEntity); + break; + case "User": + SetupSyncUser(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "Role": + DesetupSyncRole(false, true); + break; + case "User": + DesetupSyncUser(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_role!=null) + { + toReturn.Add(_role); + } + if(_user!=null) + { + toReturn.Add(_user); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, System.Int32 userID) + { + return FetchUsingPK(roleID, userID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, System.Int32 userID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(roleID, userID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(roleID, userID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 roleID, System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(roleID, userID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.RoleID, this.UserID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(RoleUserFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(RoleUserFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new RoleUserRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public RoleEntity GetSingleRole() + { + return GetSingleRole(false); + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public virtual RoleEntity GetSingleRole(bool forceFetch) + { + if( ( !_alreadyFetchedRole || forceFetch || _alwaysFetchRole) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(RoleUserEntity.Relations.RoleEntityUsingRoleID); + + RoleEntity newEntity = new RoleEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.RoleID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (RoleEntity)base.ActiveContext.Get(newEntity); + } + this.Role = newEntity; + } + else + { + if(_roleReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_role == null))) + { + this.Role = newEntity; + } + } + else + { + this.Role = null; + } + } + _alreadyFetchedRole = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _role; + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSingleUser() + { + return GetSingleUser(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSingleUser(bool forceFetch) + { + if( ( !_alreadyFetchedUser || forceFetch || _alwaysFetchUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(RoleUserEntity.Relations.UserEntityUsingUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.UserID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.User = newEntity; + } + else + { + if(_userReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_user == null))) + { + this.User = newEntity; + } + } + else + { + this.User = null; + } + } + _alreadyFetchedUser = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _user; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + RoleUserDAO dao = (RoleUserDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_role!=null) + { + _role.ActiveContext = base.ActiveContext; + } + if(_user!=null) + { + _user.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + RoleUserDAO dao = (RoleUserDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + RoleUserDAO dao = (RoleUserDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.RoleUserEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("Role", _role); + toReturn.Add("User", _user); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// The validator object for this RoleUserEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 roleID, System.Int32 userID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(roleID, userID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _role = null; + _roleReturnsNewIfNotFound = true; + _alwaysFetchRole = false; + _alreadyFetchedRole = false; + _user = null; + _userReturnsNewIfNotFound = true; + _alwaysFetchUser = false; + _alreadyFetchedUser = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("RoleID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("UserID", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _role + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncRole(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _role, new PropertyChangedEventHandler( OnRolePropertyChanged ), "Role", RoleUserEntity.Relations.RoleEntityUsingRoleID, true, signalRelatedEntity, "RoleUser", resetFKFields, new int[] { (int)RoleUserFieldIndex.RoleID } ); + _role = null; + } + + /// setups the sync logic for member _role + /// Instance to set as the related entity of type entityType + private void SetupSyncRole(IEntity relatedEntity) + { + if(_role!=relatedEntity) + { + DesetupSyncRole(true, true); + _role = (RoleEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _role, new PropertyChangedEventHandler( OnRolePropertyChanged ), "Role", RoleUserEntity.Relations.RoleEntityUsingRoleID, true, ref _alreadyFetchedRole, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnRolePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _user + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncUser(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _user, new PropertyChangedEventHandler( OnUserPropertyChanged ), "User", RoleUserEntity.Relations.UserEntityUsingUserID, true, signalRelatedEntity, "RoleUser", resetFKFields, new int[] { (int)RoleUserFieldIndex.UserID } ); + _user = null; + } + + /// setups the sync logic for member _user + /// Instance to set as the related entity of type entityType + private void SetupSyncUser(IEntity relatedEntity) + { + if(_user!=relatedEntity) + { + DesetupSyncUser(true, true); + _user = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _user, new PropertyChangedEventHandler( OnUserPropertyChanged ), "User", RoleUserEntity.Relations.UserEntityUsingUserID, true, ref _alreadyFetchedUser, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnUserPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 roleID, System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)RoleUserFieldIndex.RoleID].ForcedCurrentValueWrite(roleID); + base.Fields[(int)RoleUserFieldIndex.UserID].ForcedCurrentValueWrite(userID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateRoleUserDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new RoleUserEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static RoleUserRelations Relations + { + get { return new RoleUserRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRole + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), + (IEntityRelation)GetRelationsForField("Role")[0], (int)SD.HnD.DAL.EntityType.RoleUserEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, null, "Role", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("User")[0], (int)SD.HnD.DAL.EntityType.RoleUserEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "User", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "RoleUserEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return RoleUserEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return RoleUserEntity.FieldsCustomProperties;} + } + + /// The RoleID property of the Entity RoleUser

+ ///
+ /// Mapped on table field: "RoleUser"."RoleID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 RoleID + { + get { return (System.Int32)GetValue((int)RoleUserFieldIndex.RoleID, true); } + set { SetValue((int)RoleUserFieldIndex.RoleID, value, true); } + } + /// The UserID property of the Entity RoleUser

+ ///
+ /// Mapped on table field: "RoleUser"."UserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 UserID + { + get { return (System.Int32)GetValue((int)RoleUserFieldIndex.UserID, true); } + set { SetValue((int)RoleUserFieldIndex.UserID, value, true); } + } + + + + /// Gets / sets related entity of type 'RoleEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleRole()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual RoleEntity Role + { + get { return GetSingleRole(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncRole(value); + } + else + { + if(value==null) + { + if(_role != null) + { + _role.UnsetRelatedEntity(this, "RoleUser"); + } + } + else + { + if(_role!=value) + { + ((IEntity)value).SetRelatedEntity(this, "RoleUser"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Role. When set to true, Role is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Role is accessed. You can always execute + /// a forced fetch by calling GetSingleRole(true). + [Browsable(false)] + public bool AlwaysFetchRole + { + get { return _alwaysFetchRole; } + set { _alwaysFetchRole = value; } + } + + /// Gets / Sets the lazy loading flag if the property Role already has been fetched. Setting this property to false when Role has been fetched + /// will set Role to null as well. Setting this property to true while Role hasn't been fetched disables lazy loading for Role + [Browsable(false)] + public bool AlreadyFetchedRole + { + get { return _alreadyFetchedRole;} + set + { + if(_alreadyFetchedRole && !value) + { + this.Role = null; + } + _alreadyFetchedRole = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Role is not found + /// in the database. When set to true, Role will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool RoleReturnsNewIfNotFound + { + get { return _roleReturnsNewIfNotFound; } + set { _roleReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity User + { + get { return GetSingleUser(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncUser(value); + } + else + { + if(value==null) + { + if(_user != null) + { + _user.UnsetRelatedEntity(this, "RoleUser"); + } + } + else + { + if(_user!=value) + { + ((IEntity)value).SetRelatedEntity(this, "RoleUser"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for User. When set to true, User is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time User is accessed. You can always execute + /// a forced fetch by calling GetSingleUser(true). + [Browsable(false)] + public bool AlwaysFetchUser + { + get { return _alwaysFetchUser; } + set { _alwaysFetchUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property User already has been fetched. Setting this property to false when User has been fetched + /// will set User to null as well. Setting this property to true while User hasn't been fetched disables lazy loading for User + [Browsable(false)] + public bool AlreadyFetchedUser + { + get { return _alreadyFetchedUser;} + set + { + if(_alreadyFetchedUser && !value) + { + this.User = null; + } + _alreadyFetchedUser = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property User is not found + /// in the database. When set to true, User will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool UserReturnsNewIfNotFound + { + get { return _userReturnsNewIfNotFound; } + set { _userReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.RoleUserEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/SectionEntityBase.cs b/DAL/EntityBaseClasses/SectionEntityBase.cs new file mode 100644 index 0000000..d97e7b7 --- /dev/null +++ b/DAL/EntityBaseClasses/SectionEntityBase.cs @@ -0,0 +1,809 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'Section'.

+ /// + ///
+ [Serializable] + public abstract partial class SectionEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.ForumCollection _forums; + private bool _alwaysFetchForums, _alreadyFetchedForums; + + + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + + /// Member name Forums + public static readonly string Forums = "Forums"; + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static SectionEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public SectionEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for Section which data should be fetched into this Section object + public SectionEntityBase(System.Int32 sectionID) + { + InitClassFetch(sectionID, null, null); + } + + /// CTor + /// PK value for Section which data should be fetched into this Section object + /// the PrefetchPath which defines the graph of objects to fetch as well + public SectionEntityBase(System.Int32 sectionID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(sectionID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for Section which data should be fetched into this Section object + /// The custom validator object for this SectionEntity + public SectionEntityBase(System.Int32 sectionID, IValidator validator) + { + InitClassFetch(sectionID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected SectionEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _forums = (SD.HnD.DAL.CollectionClasses.ForumCollection)info.GetValue("_forums", typeof(SD.HnD.DAL.CollectionClasses.ForumCollection)); + _alwaysFetchForums = info.GetBoolean("_alwaysFetchForums"); + _alreadyFetchedForums = info.GetBoolean("_alreadyFetchedForums"); + + + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((SectionFieldIndex)fieldIndex) + { + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedForums = (_forums.Count > 0); + + + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return SectionEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + + case "Forums": + toReturn.Add(SectionEntity.Relations.ForumEntityUsingSectionID); + break; + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_forums", (!this.MarkedForDeletion?_forums:null)); + info.AddValue("_alwaysFetchForums", _alwaysFetchForums); + info.AddValue("_alreadyFetchedForums", _alreadyFetchedForums); + + + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + + case "Forums": + _alreadyFetchedForums = true; + if(entity!=null) + { + this.Forums.Add((ForumEntity)entity); + } + break; + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + + case "Forums": + _forums.Add((ForumEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + + case "Forums": + base.PerformRelatedEntityRemoval(_forums, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_forums); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Section which data should be fetched into this Section object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 sectionID) + { + return FetchUsingPK(sectionID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Section which data should be fetched into this Section object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 sectionID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(sectionID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Section which data should be fetched into this Section object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 sectionID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(sectionID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Section which data should be fetched into this Section object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 sectionID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(sectionID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.SectionID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(SectionFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(SectionFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new SectionRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ForumEntity' + public SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiForums(bool forceFetch) + { + return GetMultiForums(forceFetch, _forums.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ForumEntity' + public SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiForums(bool forceFetch, IPredicateExpression filter) + { + return GetMultiForums(forceFetch, _forums.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiForums(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiForums(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiForums(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedForums || forceFetch || _alwaysFetchForums) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_forums.ParticipatesInTransaction) + { + base.Transaction.Add(_forums); + } + } + _forums.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _forums.EntityFactoryToUse = entityFactoryToUse; + } + _forums.GetMultiManyToOne(this, null, filter); + _forums.SuppressClearInGetMulti=false; + _alreadyFetchedForums = true; + } + return _forums; + } + + /// Sets the collection parameters for the collection for 'Forums'. These settings will be taken into account + /// when the property Forums is requested or GetMultiForums is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersForums(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _forums.SortClauses=sortClauses; + _forums.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + SectionDAO dao = (SectionDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _forums.ActiveContext = base.ActiveContext; + + + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + SectionDAO dao = (SectionDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + SectionDAO dao = (SectionDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SectionEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + + toReturn.Add("Forums", _forums); + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for Section which data should be fetched into this Section object + /// The validator object for this SectionEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 sectionID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(sectionID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _forums = new SD.HnD.DAL.CollectionClasses.ForumCollection(new ForumEntityFactory()); + _forums.SetContainingEntityInfo(this, "Section"); + _alwaysFetchForums = false; + _alreadyFetchedForums = false; + + + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("SectionID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("SectionName", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("SectionDescription", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("OrderNo", fieldHashtable); + } + #endregion + + + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for Section which data should be fetched into this Section object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 sectionID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)SectionFieldIndex.SectionID].ForcedCurrentValueWrite(sectionID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateSectionDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new SectionEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static SectionRelations Relations + { + get { return new SectionRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Forum' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathForums + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ForumCollection(), + (IEntityRelation)GetRelationsForField("Forums")[0], (int)SD.HnD.DAL.EntityType.SectionEntity, (int)SD.HnD.DAL.EntityType.ForumEntity, 0, null, null, null, "Forums", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "SectionEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return SectionEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return SectionEntity.FieldsCustomProperties;} + } + + /// The SectionID property of the Entity Section

+ ///
+ /// Mapped on table field: "Section"."SectionID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 SectionID + { + get { return (System.Int32)GetValue((int)SectionFieldIndex.SectionID, true); } + set { SetValue((int)SectionFieldIndex.SectionID, value, true); } + } + /// The SectionName property of the Entity Section

+ ///
+ /// Mapped on table field: "Section"."SectionName"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 50
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String SectionName + { + get { return (System.String)GetValue((int)SectionFieldIndex.SectionName, true); } + set { SetValue((int)SectionFieldIndex.SectionName, value, true); } + } + /// The SectionDescription property of the Entity Section

+ ///
+ /// Mapped on table field: "Section"."SectionDescription"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 250
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String SectionDescription + { + get { return (System.String)GetValue((int)SectionFieldIndex.SectionDescription, true); } + set { SetValue((int)SectionFieldIndex.SectionDescription, value, true); } + } + /// The OrderNo property of the Entity Section

+ ///
+ /// Mapped on table field: "Section"."OrderNo"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int16 OrderNo + { + get { return (System.Int16)GetValue((int)SectionFieldIndex.OrderNo, true); } + set { SetValue((int)SectionFieldIndex.OrderNo, value, true); } + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiForums()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ForumCollection Forums + { + get { return GetMultiForums(false); } + } + + /// Gets / sets the lazy loading flag for Forums. When set to true, Forums is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Forums is accessed. You can always execute + /// a forced fetch by calling GetMultiForums(true). + [Browsable(false)] + public bool AlwaysFetchForums + { + get { return _alwaysFetchForums; } + set { _alwaysFetchForums = value; } + } + + /// Gets / Sets the lazy loading flag if the property Forums already has been fetched. Setting this property to false when Forums has been fetched + /// will clear the Forums collection well. Setting this property to true while Forums hasn't been fetched disables lazy loading for Forums + [Browsable(false)] + public bool AlreadyFetchedForums + { + get { return _alreadyFetchedForums;} + set + { + if(_alreadyFetchedForums && !value && (_forums != null)) + { + _forums.Clear(); + } + _alreadyFetchedForums = value; + } + } + + + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.SectionEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/SupportQueueEntityBase.cs b/DAL/EntityBaseClasses/SupportQueueEntityBase.cs new file mode 100644 index 0000000..5a5e958 --- /dev/null +++ b/DAL/EntityBaseClasses/SupportQueueEntityBase.cs @@ -0,0 +1,952 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'SupportQueue'.

+ /// + ///
+ [Serializable] + public abstract partial class SupportQueueEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.ForumCollection _defaultForForums; + private bool _alwaysFetchDefaultForForums, _alreadyFetchedDefaultForForums; + private SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection _supportQueueThreads; + private bool _alwaysFetchSupportQueueThreads, _alreadyFetchedSupportQueueThreads; + + + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + + /// Member name DefaultForForums + public static readonly string DefaultForForums = "DefaultForForums"; + /// Member name SupportQueueThreads + public static readonly string SupportQueueThreads = "SupportQueueThreads"; + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static SupportQueueEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public SupportQueueEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + public SupportQueueEntityBase(System.Int32 queueID) + { + InitClassFetch(queueID, null, null); + } + + /// CTor + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// the PrefetchPath which defines the graph of objects to fetch as well + public SupportQueueEntityBase(System.Int32 queueID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(queueID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// The custom validator object for this SupportQueueEntity + public SupportQueueEntityBase(System.Int32 queueID, IValidator validator) + { + InitClassFetch(queueID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected SupportQueueEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _defaultForForums = (SD.HnD.DAL.CollectionClasses.ForumCollection)info.GetValue("_defaultForForums", typeof(SD.HnD.DAL.CollectionClasses.ForumCollection)); + _alwaysFetchDefaultForForums = info.GetBoolean("_alwaysFetchDefaultForForums"); + _alreadyFetchedDefaultForForums = info.GetBoolean("_alreadyFetchedDefaultForForums"); + _supportQueueThreads = (SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection)info.GetValue("_supportQueueThreads", typeof(SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection)); + _alwaysFetchSupportQueueThreads = info.GetBoolean("_alwaysFetchSupportQueueThreads"); + _alreadyFetchedSupportQueueThreads = info.GetBoolean("_alreadyFetchedSupportQueueThreads"); + + + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((SupportQueueFieldIndex)fieldIndex) + { + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedDefaultForForums = (_defaultForForums.Count > 0); + _alreadyFetchedSupportQueueThreads = (_supportQueueThreads.Count > 0); + + + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return SupportQueueEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + + case "DefaultForForums": + toReturn.Add(SupportQueueEntity.Relations.ForumEntityUsingDefaultSupportQueueID); + break; + case "SupportQueueThreads": + toReturn.Add(SupportQueueEntity.Relations.SupportQueueThreadEntityUsingQueueID); + break; + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_defaultForForums", (!this.MarkedForDeletion?_defaultForForums:null)); + info.AddValue("_alwaysFetchDefaultForForums", _alwaysFetchDefaultForForums); + info.AddValue("_alreadyFetchedDefaultForForums", _alreadyFetchedDefaultForForums); + info.AddValue("_supportQueueThreads", (!this.MarkedForDeletion?_supportQueueThreads:null)); + info.AddValue("_alwaysFetchSupportQueueThreads", _alwaysFetchSupportQueueThreads); + info.AddValue("_alreadyFetchedSupportQueueThreads", _alreadyFetchedSupportQueueThreads); + + + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + + case "DefaultForForums": + _alreadyFetchedDefaultForForums = true; + if(entity!=null) + { + this.DefaultForForums.Add((ForumEntity)entity); + } + break; + case "SupportQueueThreads": + _alreadyFetchedSupportQueueThreads = true; + if(entity!=null) + { + this.SupportQueueThreads.Add((SupportQueueThreadEntity)entity); + } + break; + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + + case "DefaultForForums": + _defaultForForums.Add((ForumEntity)relatedEntity); + break; + case "SupportQueueThreads": + _supportQueueThreads.Add((SupportQueueThreadEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + + case "DefaultForForums": + base.PerformRelatedEntityRemoval(_defaultForForums, relatedEntity, signalRelatedEntityManyToOne); + break; + case "SupportQueueThreads": + base.PerformRelatedEntityRemoval(_supportQueueThreads, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_defaultForForums); + toReturn.Add(_supportQueueThreads); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 queueID) + { + return FetchUsingPK(queueID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 queueID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(queueID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 queueID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(queueID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 queueID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(queueID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.QueueID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(SupportQueueFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(SupportQueueFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new SupportQueueRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ForumEntity' + public SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiDefaultForForums(bool forceFetch) + { + return GetMultiDefaultForForums(forceFetch, _defaultForForums.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ForumEntity' + public SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiDefaultForForums(bool forceFetch, IPredicateExpression filter) + { + return GetMultiDefaultForForums(forceFetch, _defaultForForums.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiDefaultForForums(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiDefaultForForums(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiDefaultForForums(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedDefaultForForums || forceFetch || _alwaysFetchDefaultForForums) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_defaultForForums.ParticipatesInTransaction) + { + base.Transaction.Add(_defaultForForums); + } + } + _defaultForForums.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _defaultForForums.EntityFactoryToUse = entityFactoryToUse; + } + _defaultForForums.GetMultiManyToOne(null, this, filter); + _defaultForForums.SuppressClearInGetMulti=false; + _alreadyFetchedDefaultForForums = true; + } + return _defaultForForums; + } + + /// Sets the collection parameters for the collection for 'DefaultForForums'. These settings will be taken into account + /// when the property DefaultForForums is requested or GetMultiDefaultForForums is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersDefaultForForums(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _defaultForForums.SortClauses=sortClauses; + _defaultForForums.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'SupportQueueThreadEntity' + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreads(bool forceFetch) + { + return GetMultiSupportQueueThreads(forceFetch, _supportQueueThreads.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'SupportQueueThreadEntity' + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreads(bool forceFetch, IPredicateExpression filter) + { + return GetMultiSupportQueueThreads(forceFetch, _supportQueueThreads.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreads(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiSupportQueueThreads(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreads(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedSupportQueueThreads || forceFetch || _alwaysFetchSupportQueueThreads) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_supportQueueThreads.ParticipatesInTransaction) + { + base.Transaction.Add(_supportQueueThreads); + } + } + _supportQueueThreads.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _supportQueueThreads.EntityFactoryToUse = entityFactoryToUse; + } + _supportQueueThreads.GetMultiManyToOne(this, null, null, filter); + _supportQueueThreads.SuppressClearInGetMulti=false; + _alreadyFetchedSupportQueueThreads = true; + } + return _supportQueueThreads; + } + + /// Sets the collection parameters for the collection for 'SupportQueueThreads'. These settings will be taken into account + /// when the property SupportQueueThreads is requested or GetMultiSupportQueueThreads is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersSupportQueueThreads(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _supportQueueThreads.SortClauses=sortClauses; + _supportQueueThreads.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + SupportQueueDAO dao = (SupportQueueDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _defaultForForums.ActiveContext = base.ActiveContext; + _supportQueueThreads.ActiveContext = base.ActiveContext; + + + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + SupportQueueDAO dao = (SupportQueueDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + SupportQueueDAO dao = (SupportQueueDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SupportQueueEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + + toReturn.Add("DefaultForForums", _defaultForForums); + toReturn.Add("SupportQueueThreads", _supportQueueThreads); + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// The validator object for this SupportQueueEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 queueID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(queueID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _defaultForForums = new SD.HnD.DAL.CollectionClasses.ForumCollection(new ForumEntityFactory()); + _defaultForForums.SetContainingEntityInfo(this, "DefaultSupportQueue"); + _alwaysFetchDefaultForForums = false; + _alreadyFetchedDefaultForForums = false; + _supportQueueThreads = new SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection(new SupportQueueThreadEntityFactory()); + _supportQueueThreads.SetContainingEntityInfo(this, "SupportQueue"); + _alwaysFetchSupportQueueThreads = false; + _alreadyFetchedSupportQueueThreads = false; + + + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("QueueID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("QueueName", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("QueueDescription", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("OrderNo", fieldHashtable); + } + #endregion + + + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 queueID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)SupportQueueFieldIndex.QueueID].ForcedCurrentValueWrite(queueID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateSupportQueueDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new SupportQueueEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static SupportQueueRelations Relations + { + get { return new SupportQueueRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Forum' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathDefaultForForums + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ForumCollection(), + (IEntityRelation)GetRelationsForField("DefaultForForums")[0], (int)SD.HnD.DAL.EntityType.SupportQueueEntity, (int)SD.HnD.DAL.EntityType.ForumEntity, 0, null, null, null, "DefaultForForums", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'SupportQueueThread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSupportQueueThreads + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection(), + (IEntityRelation)GetRelationsForField("SupportQueueThreads")[0], (int)SD.HnD.DAL.EntityType.SupportQueueEntity, (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity, 0, null, null, null, "SupportQueueThreads", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "SupportQueueEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return SupportQueueEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return SupportQueueEntity.FieldsCustomProperties;} + } + + /// The QueueID property of the Entity SupportQueue

+ ///
+ /// Mapped on table field: "SupportQueue"."QueueID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 QueueID + { + get { return (System.Int32)GetValue((int)SupportQueueFieldIndex.QueueID, true); } + set { SetValue((int)SupportQueueFieldIndex.QueueID, value, true); } + } + /// The QueueName property of the Entity SupportQueue

+ ///
+ /// Mapped on table field: "SupportQueue"."QueueName"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 50
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String QueueName + { + get { return (System.String)GetValue((int)SupportQueueFieldIndex.QueueName, true); } + set { SetValue((int)SupportQueueFieldIndex.QueueName, value, true); } + } + /// The QueueDescription property of the Entity SupportQueue

+ ///
+ /// Mapped on table field: "SupportQueue"."QueueDescription"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 250
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String QueueDescription + { + get { return (System.String)GetValue((int)SupportQueueFieldIndex.QueueDescription, true); } + set { SetValue((int)SupportQueueFieldIndex.QueueDescription, value, true); } + } + /// The OrderNo property of the Entity SupportQueue

+ ///
+ /// Mapped on table field: "SupportQueue"."OrderNo"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int16 OrderNo + { + get { return (System.Int16)GetValue((int)SupportQueueFieldIndex.OrderNo, true); } + set { SetValue((int)SupportQueueFieldIndex.OrderNo, value, true); } + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiDefaultForForums()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ForumCollection DefaultForForums + { + get { return GetMultiDefaultForForums(false); } + } + + /// Gets / sets the lazy loading flag for DefaultForForums. When set to true, DefaultForForums is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time DefaultForForums is accessed. You can always execute + /// a forced fetch by calling GetMultiDefaultForForums(true). + [Browsable(false)] + public bool AlwaysFetchDefaultForForums + { + get { return _alwaysFetchDefaultForForums; } + set { _alwaysFetchDefaultForForums = value; } + } + + /// Gets / Sets the lazy loading flag if the property DefaultForForums already has been fetched. Setting this property to false when DefaultForForums has been fetched + /// will clear the DefaultForForums collection well. Setting this property to true while DefaultForForums hasn't been fetched disables lazy loading for DefaultForForums + [Browsable(false)] + public bool AlreadyFetchedDefaultForForums + { + get { return _alreadyFetchedDefaultForForums;} + set + { + if(_alreadyFetchedDefaultForForums && !value && (_defaultForForums != null)) + { + _defaultForForums.Clear(); + } + _alreadyFetchedDefaultForForums = value; + } + } + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiSupportQueueThreads()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection SupportQueueThreads + { + get { return GetMultiSupportQueueThreads(false); } + } + + /// Gets / sets the lazy loading flag for SupportQueueThreads. When set to true, SupportQueueThreads is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SupportQueueThreads is accessed. You can always execute + /// a forced fetch by calling GetMultiSupportQueueThreads(true). + [Browsable(false)] + public bool AlwaysFetchSupportQueueThreads + { + get { return _alwaysFetchSupportQueueThreads; } + set { _alwaysFetchSupportQueueThreads = value; } + } + + /// Gets / Sets the lazy loading flag if the property SupportQueueThreads already has been fetched. Setting this property to false when SupportQueueThreads has been fetched + /// will clear the SupportQueueThreads collection well. Setting this property to true while SupportQueueThreads hasn't been fetched disables lazy loading for SupportQueueThreads + [Browsable(false)] + public bool AlreadyFetchedSupportQueueThreads + { + get { return _alreadyFetchedSupportQueueThreads;} + set + { + if(_alreadyFetchedSupportQueueThreads && !value && (_supportQueueThreads != null)) + { + _supportQueueThreads.Clear(); + } + _alreadyFetchedSupportQueueThreads = value; + } + } + + + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.SupportQueueEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/SupportQueueThreadEntityBase.cs b/DAL/EntityBaseClasses/SupportQueueThreadEntityBase.cs new file mode 100644 index 0000000..714b5a6 --- /dev/null +++ b/DAL/EntityBaseClasses/SupportQueueThreadEntityBase.cs @@ -0,0 +1,1611 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'SupportQueueThread'.

+ /// + ///
+ [Serializable] + public abstract partial class SupportQueueThreadEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private SupportQueueEntity _supportQueue; + private bool _alwaysFetchSupportQueue, _alreadyFetchedSupportQueue, _supportQueueReturnsNewIfNotFound; + private UserEntity _claimedByUser; + private bool _alwaysFetchClaimedByUser, _alreadyFetchedClaimedByUser, _claimedByUserReturnsNewIfNotFound; + private UserEntity _placedInQueueByUser; + private bool _alwaysFetchPlacedInQueueByUser, _alreadyFetchedPlacedInQueueByUser, _placedInQueueByUserReturnsNewIfNotFound; + private ThreadEntity _thread; + private bool _alwaysFetchThread, _alreadyFetchedThread, _threadReturnsNewIfNotFound; + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name SupportQueue + public static readonly string SupportQueue = "SupportQueue"; + /// Member name ClaimedByUser + public static readonly string ClaimedByUser = "ClaimedByUser"; + /// Member name PlacedInQueueByUser + public static readonly string PlacedInQueueByUser = "PlacedInQueueByUser"; + + + /// Member name Thread + public static readonly string Thread = "Thread"; + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static SupportQueueThreadEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public SupportQueueThreadEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + public SupportQueueThreadEntityBase(System.Int32 queueID, System.Int32 threadID) + { + InitClassFetch(queueID, threadID, null, null); + } + + /// CTor + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// the PrefetchPath which defines the graph of objects to fetch as well + public SupportQueueThreadEntityBase(System.Int32 queueID, System.Int32 threadID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(queueID, threadID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// The custom validator object for this SupportQueueThreadEntity + public SupportQueueThreadEntityBase(System.Int32 queueID, System.Int32 threadID, IValidator validator) + { + InitClassFetch(queueID, threadID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected SupportQueueThreadEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _supportQueue = (SupportQueueEntity)info.GetValue("_supportQueue", typeof(SupportQueueEntity)); + if(_supportQueue!=null) + { + _supportQueue.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _supportQueueReturnsNewIfNotFound = info.GetBoolean("_supportQueueReturnsNewIfNotFound"); + _alwaysFetchSupportQueue = info.GetBoolean("_alwaysFetchSupportQueue"); + _alreadyFetchedSupportQueue = info.GetBoolean("_alreadyFetchedSupportQueue"); + _claimedByUser = (UserEntity)info.GetValue("_claimedByUser", typeof(UserEntity)); + if(_claimedByUser!=null) + { + _claimedByUser.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _claimedByUserReturnsNewIfNotFound = info.GetBoolean("_claimedByUserReturnsNewIfNotFound"); + _alwaysFetchClaimedByUser = info.GetBoolean("_alwaysFetchClaimedByUser"); + _alreadyFetchedClaimedByUser = info.GetBoolean("_alreadyFetchedClaimedByUser"); + _placedInQueueByUser = (UserEntity)info.GetValue("_placedInQueueByUser", typeof(UserEntity)); + if(_placedInQueueByUser!=null) + { + _placedInQueueByUser.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _placedInQueueByUserReturnsNewIfNotFound = info.GetBoolean("_placedInQueueByUserReturnsNewIfNotFound"); + _alwaysFetchPlacedInQueueByUser = info.GetBoolean("_alwaysFetchPlacedInQueueByUser"); + _alreadyFetchedPlacedInQueueByUser = info.GetBoolean("_alreadyFetchedPlacedInQueueByUser"); + _thread = (ThreadEntity)info.GetValue("_thread", typeof(ThreadEntity)); + if(_thread!=null) + { + _thread.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _threadReturnsNewIfNotFound = info.GetBoolean("_threadReturnsNewIfNotFound"); + _alwaysFetchThread = info.GetBoolean("_alwaysFetchThread"); + _alreadyFetchedThread = info.GetBoolean("_alreadyFetchedThread"); + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((SupportQueueThreadFieldIndex)fieldIndex) + { + case SupportQueueThreadFieldIndex.QueueID: + DesetupSyncSupportQueue(true, false); + _alreadyFetchedSupportQueue = false; + break; + case SupportQueueThreadFieldIndex.ThreadID: + DesetupSyncThread(true, false); + _alreadyFetchedThread = false; + break; + case SupportQueueThreadFieldIndex.PlacedInQueueByUserID: + DesetupSyncPlacedInQueueByUser(true, false); + _alreadyFetchedPlacedInQueueByUser = false; + break; + case SupportQueueThreadFieldIndex.ClaimedByUserID: + DesetupSyncClaimedByUser(true, false); + _alreadyFetchedClaimedByUser = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedSupportQueue = (_supportQueue != null); + _alreadyFetchedClaimedByUser = (_claimedByUser != null); + _alreadyFetchedPlacedInQueueByUser = (_placedInQueueByUser != null); + _alreadyFetchedThread = (_thread != null); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return SupportQueueThreadEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "SupportQueue": + toReturn.Add(SupportQueueThreadEntity.Relations.SupportQueueEntityUsingQueueID); + break; + case "ClaimedByUser": + toReturn.Add(SupportQueueThreadEntity.Relations.UserEntityUsingClaimedByUserID); + break; + case "PlacedInQueueByUser": + toReturn.Add(SupportQueueThreadEntity.Relations.UserEntityUsingPlacedInQueueByUserID); + break; + + + case "Thread": + toReturn.Add(SupportQueueThreadEntity.Relations.ThreadEntityUsingThreadID); + break; + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_supportQueue", (!this.MarkedForDeletion?_supportQueue:null)); + info.AddValue("_supportQueueReturnsNewIfNotFound", _supportQueueReturnsNewIfNotFound); + info.AddValue("_alwaysFetchSupportQueue", _alwaysFetchSupportQueue); + info.AddValue("_alreadyFetchedSupportQueue", _alreadyFetchedSupportQueue); + info.AddValue("_claimedByUser", (!this.MarkedForDeletion?_claimedByUser:null)); + info.AddValue("_claimedByUserReturnsNewIfNotFound", _claimedByUserReturnsNewIfNotFound); + info.AddValue("_alwaysFetchClaimedByUser", _alwaysFetchClaimedByUser); + info.AddValue("_alreadyFetchedClaimedByUser", _alreadyFetchedClaimedByUser); + info.AddValue("_placedInQueueByUser", (!this.MarkedForDeletion?_placedInQueueByUser:null)); + info.AddValue("_placedInQueueByUserReturnsNewIfNotFound", _placedInQueueByUserReturnsNewIfNotFound); + info.AddValue("_alwaysFetchPlacedInQueueByUser", _alwaysFetchPlacedInQueueByUser); + info.AddValue("_alreadyFetchedPlacedInQueueByUser", _alreadyFetchedPlacedInQueueByUser); + info.AddValue("_thread", (!this.MarkedForDeletion?_thread:null)); + info.AddValue("_threadReturnsNewIfNotFound", _threadReturnsNewIfNotFound); + info.AddValue("_alwaysFetchThread", _alwaysFetchThread); + info.AddValue("_alreadyFetchedThread", _alreadyFetchedThread); + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "SupportQueue": + _alreadyFetchedSupportQueue = true; + this.SupportQueue = (SupportQueueEntity)entity; + break; + case "ClaimedByUser": + _alreadyFetchedClaimedByUser = true; + this.ClaimedByUser = (UserEntity)entity; + break; + case "PlacedInQueueByUser": + _alreadyFetchedPlacedInQueueByUser = true; + this.PlacedInQueueByUser = (UserEntity)entity; + break; + + + case "Thread": + _alreadyFetchedThread = true; + this.Thread = (ThreadEntity)entity; + break; + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "SupportQueue": + SetupSyncSupportQueue(relatedEntity); + break; + case "ClaimedByUser": + SetupSyncClaimedByUser(relatedEntity); + break; + case "PlacedInQueueByUser": + SetupSyncPlacedInQueueByUser(relatedEntity); + break; + + case "Thread": + SetupSyncThread(relatedEntity); + break; + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "SupportQueue": + DesetupSyncSupportQueue(false, true); + break; + case "ClaimedByUser": + DesetupSyncClaimedByUser(false, true); + break; + case "PlacedInQueueByUser": + DesetupSyncPlacedInQueueByUser(false, true); + break; + + case "Thread": + DesetupSyncThread(false, true); + break; + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_supportQueue!=null) + { + toReturn.Add(_supportQueue); + } + if(_claimedByUser!=null) + { + toReturn.Add(_claimedByUser); + } + if(_placedInQueueByUser!=null) + { + toReturn.Add(_placedInQueueByUser); + } + + if(_thread!=null) + { + toReturn.Add(_thread); + } + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Method which will try to fetch the contents for this entity using a unique constraint. + /// All contents of the entity is lost. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// true if succeeded and the contents is read, false otherwise + public bool FetchUsingUCThreadID(System.Int32 threadID) + { + return FetchUsingUCThreadID( threadID, null, null, null); + } + + /// Method which will try to fetch the contents for this entity using a unique constraint. + /// All contents of the entity is lost. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// the PrefetchPath which defines the graph of objects to fetch as well + /// true if succeeded and the contents is read, false otherwise + public bool FetchUsingUCThreadID(System.Int32 threadID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingUCThreadID( threadID, prefetchPathToUse, null, null); + } + + /// Method which will try to fetch the contents for this entity using a unique constraint. + /// All contents of the entity is lost. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// true if succeeded and the contents is read, false otherwise + public bool FetchUsingUCThreadID(System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return FetchUsingUCThreadID( threadID, prefetchPathToUse, contextToUse, null); + } + + /// Method which will try to fetch the contents for this entity using a unique constraint. + /// All contents of the entity is lost. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// true if succeeded and the contents is read, false otherwise + public bool FetchUsingUCThreadID(System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + SupportQueueThreadDAO dao = (SupportQueueThreadDAO)CreateDAOInstance(); + dao.FetchSupportQueueThreadUsingUCThreadID(this, base.Transaction, threadID, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 queueID, System.Int32 threadID) + { + return FetchUsingPK(queueID, threadID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 queueID, System.Int32 threadID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(queueID, threadID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 queueID, System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(queueID, threadID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 queueID, System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(queueID, threadID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.QueueID, this.ThreadID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(SupportQueueThreadFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(SupportQueueThreadFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new SupportQueueThreadRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'SupportQueueEntity', using a relation of type 'n:1' + /// A fetched entity of type 'SupportQueueEntity' which is related to this entity. + public SupportQueueEntity GetSingleSupportQueue() + { + return GetSingleSupportQueue(false); + } + + /// Retrieves the related entity of type 'SupportQueueEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'SupportQueueEntity' which is related to this entity. + public virtual SupportQueueEntity GetSingleSupportQueue(bool forceFetch) + { + if( ( !_alreadyFetchedSupportQueue || forceFetch || _alwaysFetchSupportQueue) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(SupportQueueThreadEntity.Relations.SupportQueueEntityUsingQueueID); + + SupportQueueEntity newEntity = new SupportQueueEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.QueueID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (SupportQueueEntity)base.ActiveContext.Get(newEntity); + } + this.SupportQueue = newEntity; + } + else + { + if(_supportQueueReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_supportQueue == null))) + { + this.SupportQueue = newEntity; + } + } + else + { + this.SupportQueue = null; + } + } + _alreadyFetchedSupportQueue = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _supportQueue; + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSingleClaimedByUser() + { + return GetSingleClaimedByUser(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSingleClaimedByUser(bool forceFetch) + { + if( ( !_alreadyFetchedClaimedByUser || forceFetch || _alwaysFetchClaimedByUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(SupportQueueThreadEntity.Relations.UserEntityUsingClaimedByUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ClaimedByUserID.GetValueOrDefault()); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.ClaimedByUser = newEntity; + } + else + { + if(_claimedByUserReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_claimedByUser == null))) + { + this.ClaimedByUser = newEntity; + } + } + else + { + this.ClaimedByUser = null; + } + } + _alreadyFetchedClaimedByUser = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _claimedByUser; + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSinglePlacedInQueueByUser() + { + return GetSinglePlacedInQueueByUser(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSinglePlacedInQueueByUser(bool forceFetch) + { + if( ( !_alreadyFetchedPlacedInQueueByUser || forceFetch || _alwaysFetchPlacedInQueueByUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(SupportQueueThreadEntity.Relations.UserEntityUsingPlacedInQueueByUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.PlacedInQueueByUserID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.PlacedInQueueByUser = newEntity; + } + else + { + if(_placedInQueueByUserReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_placedInQueueByUser == null))) + { + this.PlacedInQueueByUser = newEntity; + } + } + else + { + this.PlacedInQueueByUser = null; + } + } + _alreadyFetchedPlacedInQueueByUser = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _placedInQueueByUser; + } + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type '1:1' + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public ThreadEntity GetSingleThread() + { + return GetSingleThread(false); + } + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type '1:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public virtual ThreadEntity GetSingleThread(bool forceFetch) + { + if( ( !_alreadyFetchedThread || forceFetch || _alwaysFetchThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode ) + { + ThreadEntity newEntity = new ThreadEntity(); + IEntityRelation relation = SupportQueueThreadEntity.Relations.ThreadEntityUsingThreadID; + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + + + bool fetchResult = false; + if(base.CheckIfLazyLoadingShouldOccur(relation)) + { + fetchResult = newEntity.FetchUsingPK(this.ThreadID); + } + if(!_threadReturnsNewIfNotFound && !fetchResult) + { + this.Thread = null; + } + else + { + if((base.ActiveContext!=null)&&fetchResult) + { + newEntity = (ThreadEntity)base.ActiveContext.Get(newEntity); + } + this.Thread = newEntity; + _alreadyFetchedThread = fetchResult; + } + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _thread; + } + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + SupportQueueThreadDAO dao = (SupportQueueThreadDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_supportQueue!=null) + { + _supportQueue.ActiveContext = base.ActiveContext; + } + if(_claimedByUser!=null) + { + _claimedByUser.ActiveContext = base.ActiveContext; + } + if(_placedInQueueByUser!=null) + { + _placedInQueueByUser.ActiveContext = base.ActiveContext; + } + if(_thread!=null) + { + _thread.ActiveContext = base.ActiveContext; + } + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + SupportQueueThreadDAO dao = (SupportQueueThreadDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + SupportQueueThreadDAO dao = (SupportQueueThreadDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SupportQueueThreadEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("SupportQueue", _supportQueue); + toReturn.Add("ClaimedByUser", _claimedByUser); + toReturn.Add("PlacedInQueueByUser", _placedInQueueByUser); + + + toReturn.Add("Thread", _thread); + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// The validator object for this SupportQueueThreadEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 queueID, System.Int32 threadID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(queueID, threadID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _supportQueue = null; + _supportQueueReturnsNewIfNotFound = true; + _alwaysFetchSupportQueue = false; + _alreadyFetchedSupportQueue = false; + _claimedByUser = null; + _claimedByUserReturnsNewIfNotFound = true; + _alwaysFetchClaimedByUser = false; + _alreadyFetchedClaimedByUser = false; + _placedInQueueByUser = null; + _placedInQueueByUserReturnsNewIfNotFound = true; + _alwaysFetchPlacedInQueueByUser = false; + _alreadyFetchedPlacedInQueueByUser = false; + _thread = null; + _threadReturnsNewIfNotFound = true; + _alwaysFetchThread = false; + _alreadyFetchedThread = false; + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("QueueID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("PlacedInQueueByUserID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("PlacedInQueueOn", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ClaimedByUserID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ClaimedOn", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _supportQueue + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncSupportQueue(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _supportQueue, new PropertyChangedEventHandler( OnSupportQueuePropertyChanged ), "SupportQueue", SupportQueueThreadEntity.Relations.SupportQueueEntityUsingQueueID, true, signalRelatedEntity, "SupportQueueThreads", resetFKFields, new int[] { (int)SupportQueueThreadFieldIndex.QueueID } ); + _supportQueue = null; + } + + /// setups the sync logic for member _supportQueue + /// Instance to set as the related entity of type entityType + private void SetupSyncSupportQueue(IEntity relatedEntity) + { + if(_supportQueue!=relatedEntity) + { + DesetupSyncSupportQueue(true, true); + _supportQueue = (SupportQueueEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _supportQueue, new PropertyChangedEventHandler( OnSupportQueuePropertyChanged ), "SupportQueue", SupportQueueThreadEntity.Relations.SupportQueueEntityUsingQueueID, true, ref _alreadyFetchedSupportQueue, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnSupportQueuePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _claimedByUser + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncClaimedByUser(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _claimedByUser, new PropertyChangedEventHandler( OnClaimedByUserPropertyChanged ), "ClaimedByUser", SupportQueueThreadEntity.Relations.UserEntityUsingClaimedByUserID, true, signalRelatedEntity, "SupportQueueThreadsClaimed", resetFKFields, new int[] { (int)SupportQueueThreadFieldIndex.ClaimedByUserID } ); + _claimedByUser = null; + } + + /// setups the sync logic for member _claimedByUser + /// Instance to set as the related entity of type entityType + private void SetupSyncClaimedByUser(IEntity relatedEntity) + { + if(_claimedByUser!=relatedEntity) + { + DesetupSyncClaimedByUser(true, true); + _claimedByUser = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _claimedByUser, new PropertyChangedEventHandler( OnClaimedByUserPropertyChanged ), "ClaimedByUser", SupportQueueThreadEntity.Relations.UserEntityUsingClaimedByUserID, true, ref _alreadyFetchedClaimedByUser, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnClaimedByUserPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _placedInQueueByUser + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncPlacedInQueueByUser(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _placedInQueueByUser, new PropertyChangedEventHandler( OnPlacedInQueueByUserPropertyChanged ), "PlacedInQueueByUser", SupportQueueThreadEntity.Relations.UserEntityUsingPlacedInQueueByUserID, true, signalRelatedEntity, "SupportQueueThreadsPlaced", resetFKFields, new int[] { (int)SupportQueueThreadFieldIndex.PlacedInQueueByUserID } ); + _placedInQueueByUser = null; + } + + /// setups the sync logic for member _placedInQueueByUser + /// Instance to set as the related entity of type entityType + private void SetupSyncPlacedInQueueByUser(IEntity relatedEntity) + { + if(_placedInQueueByUser!=relatedEntity) + { + DesetupSyncPlacedInQueueByUser(true, true); + _placedInQueueByUser = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _placedInQueueByUser, new PropertyChangedEventHandler( OnPlacedInQueueByUserPropertyChanged ), "PlacedInQueueByUser", SupportQueueThreadEntity.Relations.UserEntityUsingPlacedInQueueByUserID, true, ref _alreadyFetchedPlacedInQueueByUser, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnPlacedInQueueByUserPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _thread + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncThread(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", SupportQueueThreadEntity.Relations.ThreadEntityUsingThreadID, true, signalRelatedEntity, "SupportQueueThread", resetFKFields, new int[] { (int)SupportQueueThreadFieldIndex.ThreadID } ); + _thread = null; + } + + /// setups the sync logic for member _thread + /// Instance to set as the related entity of type entityType + private void SetupSyncThread(IEntity relatedEntity) + { + if(_thread!=relatedEntity) + { + DesetupSyncThread(true, true); + _thread = (ThreadEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", SupportQueueThreadEntity.Relations.ThreadEntityUsingThreadID, true, ref _alreadyFetchedThread, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnThreadPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 queueID, System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)SupportQueueThreadFieldIndex.QueueID].ForcedCurrentValueWrite(queueID); + base.Fields[(int)SupportQueueThreadFieldIndex.ThreadID].ForcedCurrentValueWrite(threadID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateSupportQueueThreadDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new SupportQueueThreadEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static SupportQueueThreadRelations Relations + { + get { return new SupportQueueThreadRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'SupportQueue' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSupportQueue + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SupportQueueCollection(), + (IEntityRelation)GetRelationsForField("SupportQueue")[0], (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity, (int)SD.HnD.DAL.EntityType.SupportQueueEntity, 0, null, null, null, "SupportQueue", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathClaimedByUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("ClaimedByUser")[0], (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "ClaimedByUser", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathPlacedInQueueByUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("PlacedInQueueByUser")[0], (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "PlacedInQueueByUser", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThread + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), + (IEntityRelation)GetRelationsForField("Thread")[0], (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, null, "Thread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToOne); + } + } + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "SupportQueueThreadEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return SupportQueueThreadEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return SupportQueueThreadEntity.FieldsCustomProperties;} + } + + /// The QueueID property of the Entity SupportQueueThread

+ ///
+ /// Mapped on table field: "SupportQueueThread"."QueueID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 QueueID + { + get { return (System.Int32)GetValue((int)SupportQueueThreadFieldIndex.QueueID, true); } + set { SetValue((int)SupportQueueThreadFieldIndex.QueueID, value, true); } + } + /// The ThreadID property of the Entity SupportQueueThread

+ ///
+ /// Mapped on table field: "SupportQueueThread"."ThreadID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 ThreadID + { + get { return (System.Int32)GetValue((int)SupportQueueThreadFieldIndex.ThreadID, true); } + set { SetValue((int)SupportQueueThreadFieldIndex.ThreadID, value, true); } + } + /// The PlacedInQueueByUserID property of the Entity SupportQueueThread

+ ///
+ /// Mapped on table field: "SupportQueueThread"."PlacedInQueueByUserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 PlacedInQueueByUserID + { + get { return (System.Int32)GetValue((int)SupportQueueThreadFieldIndex.PlacedInQueueByUserID, true); } + set { SetValue((int)SupportQueueThreadFieldIndex.PlacedInQueueByUserID, value, true); } + } + /// The PlacedInQueueOn property of the Entity SupportQueueThread

+ ///
+ /// Mapped on table field: "SupportQueueThread"."PlacedInQueueOn"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.DateTime PlacedInQueueOn + { + get { return (System.DateTime)GetValue((int)SupportQueueThreadFieldIndex.PlacedInQueueOn, true); } + set { SetValue((int)SupportQueueThreadFieldIndex.PlacedInQueueOn, value, true); } + } + /// The ClaimedByUserID property of the Entity SupportQueueThread

+ ///
+ /// Mapped on table field: "SupportQueueThread"."ClaimedByUserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable ClaimedByUserID + { + get { return (Nullable)GetValue((int)SupportQueueThreadFieldIndex.ClaimedByUserID, false); } + set { SetValue((int)SupportQueueThreadFieldIndex.ClaimedByUserID, value, true); } + } + /// The ClaimedOn property of the Entity SupportQueueThread

+ ///
+ /// Mapped on table field: "SupportQueueThread"."ClaimedOn"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable ClaimedOn + { + get { return (Nullable)GetValue((int)SupportQueueThreadFieldIndex.ClaimedOn, false); } + set { SetValue((int)SupportQueueThreadFieldIndex.ClaimedOn, value, true); } + } + + + + /// Gets / sets related entity of type 'SupportQueueEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleSupportQueue()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual SupportQueueEntity SupportQueue + { + get { return GetSingleSupportQueue(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncSupportQueue(value); + } + else + { + if(value==null) + { + if(_supportQueue != null) + { + _supportQueue.UnsetRelatedEntity(this, "SupportQueueThreads"); + } + } + else + { + if(_supportQueue!=value) + { + ((IEntity)value).SetRelatedEntity(this, "SupportQueueThreads"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for SupportQueue. When set to true, SupportQueue is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SupportQueue is accessed. You can always execute + /// a forced fetch by calling GetSingleSupportQueue(true). + [Browsable(false)] + public bool AlwaysFetchSupportQueue + { + get { return _alwaysFetchSupportQueue; } + set { _alwaysFetchSupportQueue = value; } + } + + /// Gets / Sets the lazy loading flag if the property SupportQueue already has been fetched. Setting this property to false when SupportQueue has been fetched + /// will set SupportQueue to null as well. Setting this property to true while SupportQueue hasn't been fetched disables lazy loading for SupportQueue + [Browsable(false)] + public bool AlreadyFetchedSupportQueue + { + get { return _alreadyFetchedSupportQueue;} + set + { + if(_alreadyFetchedSupportQueue && !value) + { + this.SupportQueue = null; + } + _alreadyFetchedSupportQueue = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property SupportQueue is not found + /// in the database. When set to true, SupportQueue will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool SupportQueueReturnsNewIfNotFound + { + get { return _supportQueueReturnsNewIfNotFound; } + set { _supportQueueReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleClaimedByUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity ClaimedByUser + { + get { return GetSingleClaimedByUser(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncClaimedByUser(value); + } + else + { + if(value==null) + { + if(_claimedByUser != null) + { + _claimedByUser.UnsetRelatedEntity(this, "SupportQueueThreadsClaimed"); + } + } + else + { + if(_claimedByUser!=value) + { + ((IEntity)value).SetRelatedEntity(this, "SupportQueueThreadsClaimed"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for ClaimedByUser. When set to true, ClaimedByUser is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ClaimedByUser is accessed. You can always execute + /// a forced fetch by calling GetSingleClaimedByUser(true). + [Browsable(false)] + public bool AlwaysFetchClaimedByUser + { + get { return _alwaysFetchClaimedByUser; } + set { _alwaysFetchClaimedByUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property ClaimedByUser already has been fetched. Setting this property to false when ClaimedByUser has been fetched + /// will set ClaimedByUser to null as well. Setting this property to true while ClaimedByUser hasn't been fetched disables lazy loading for ClaimedByUser + [Browsable(false)] + public bool AlreadyFetchedClaimedByUser + { + get { return _alreadyFetchedClaimedByUser;} + set + { + if(_alreadyFetchedClaimedByUser && !value) + { + this.ClaimedByUser = null; + } + _alreadyFetchedClaimedByUser = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property ClaimedByUser is not found + /// in the database. When set to true, ClaimedByUser will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ClaimedByUserReturnsNewIfNotFound + { + get { return _claimedByUserReturnsNewIfNotFound; } + set { _claimedByUserReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSinglePlacedInQueueByUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity PlacedInQueueByUser + { + get { return GetSinglePlacedInQueueByUser(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncPlacedInQueueByUser(value); + } + else + { + if(value==null) + { + if(_placedInQueueByUser != null) + { + _placedInQueueByUser.UnsetRelatedEntity(this, "SupportQueueThreadsPlaced"); + } + } + else + { + if(_placedInQueueByUser!=value) + { + ((IEntity)value).SetRelatedEntity(this, "SupportQueueThreadsPlaced"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for PlacedInQueueByUser. When set to true, PlacedInQueueByUser is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time PlacedInQueueByUser is accessed. You can always execute + /// a forced fetch by calling GetSinglePlacedInQueueByUser(true). + [Browsable(false)] + public bool AlwaysFetchPlacedInQueueByUser + { + get { return _alwaysFetchPlacedInQueueByUser; } + set { _alwaysFetchPlacedInQueueByUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property PlacedInQueueByUser already has been fetched. Setting this property to false when PlacedInQueueByUser has been fetched + /// will set PlacedInQueueByUser to null as well. Setting this property to true while PlacedInQueueByUser hasn't been fetched disables lazy loading for PlacedInQueueByUser + [Browsable(false)] + public bool AlreadyFetchedPlacedInQueueByUser + { + get { return _alreadyFetchedPlacedInQueueByUser;} + set + { + if(_alreadyFetchedPlacedInQueueByUser && !value) + { + this.PlacedInQueueByUser = null; + } + _alreadyFetchedPlacedInQueueByUser = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property PlacedInQueueByUser is not found + /// in the database. When set to true, PlacedInQueueByUser will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool PlacedInQueueByUserReturnsNewIfNotFound + { + get { return _placedInQueueByUserReturnsNewIfNotFound; } + set { _placedInQueueByUserReturnsNewIfNotFound = value; } + } + + /// Gets / sets related entity of type 'ThreadEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ThreadEntity Thread + { + get { return GetSingleThread(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncThread(value); + } + else + { + if(value==null) + { + DesetupSyncThread(true, true); + } + else + { + if(_thread!=value) + { + IEntity relatedEntity = (IEntity)value; + relatedEntity.SetRelatedEntity(this, "SupportQueueThread"); + SetupSyncThread(relatedEntity); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Thread. When set to true, Thread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Thread is accessed. You can always execute + /// a forced fetch by calling GetSingleThread(true). + [Browsable(false)] + public bool AlwaysFetchThread + { + get { return _alwaysFetchThread; } + set { _alwaysFetchThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property Thread already has been fetched. Setting this property to false when Thread has been fetched + /// will set Thread to null as well. Setting this property to true while Thread hasn't been fetched disables lazy loading for Thread + [Browsable(false)] + public bool AlreadyFetchedThread + { + get { return _alreadyFetchedThread;} + set + { + if(_alreadyFetchedThread && !value) + { + this.Thread = null; + } + _alreadyFetchedThread = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Thread is not found + /// in the database. When set to true, Thread will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ThreadReturnsNewIfNotFound + { + get { return _threadReturnsNewIfNotFound; } + set { _threadReturnsNewIfNotFound = value; } + } + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/SystemDataEntityBase.cs b/DAL/EntityBaseClasses/SystemDataEntityBase.cs new file mode 100644 index 0000000..97126b8 --- /dev/null +++ b/DAL/EntityBaseClasses/SystemDataEntityBase.cs @@ -0,0 +1,1170 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'SystemData'.

+ /// + ///
+ [Serializable] + public abstract partial class SystemDataEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private RoleEntity _roleForAnonymous; + private bool _alwaysFetchRoleForAnonymous, _alreadyFetchedRoleForAnonymous, _roleForAnonymousReturnsNewIfNotFound; + private RoleEntity _roleForNewUser; + private bool _alwaysFetchRoleForNewUser, _alreadyFetchedRoleForNewUser, _roleForNewUserReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name RoleForAnonymous + public static readonly string RoleForAnonymous = "RoleForAnonymous"; + /// Member name RoleForNewUser + public static readonly string RoleForNewUser = "RoleForNewUser"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static SystemDataEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public SystemDataEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for SystemData which data should be fetched into this SystemData object + public SystemDataEntityBase(System.Int32 iD) + { + InitClassFetch(iD, null, null); + } + + /// CTor + /// PK value for SystemData which data should be fetched into this SystemData object + /// the PrefetchPath which defines the graph of objects to fetch as well + public SystemDataEntityBase(System.Int32 iD, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(iD, null, prefetchPathToUse); + } + + /// CTor + /// PK value for SystemData which data should be fetched into this SystemData object + /// The custom validator object for this SystemDataEntity + public SystemDataEntityBase(System.Int32 iD, IValidator validator) + { + InitClassFetch(iD, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected SystemDataEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _roleForAnonymous = (RoleEntity)info.GetValue("_roleForAnonymous", typeof(RoleEntity)); + if(_roleForAnonymous!=null) + { + _roleForAnonymous.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _roleForAnonymousReturnsNewIfNotFound = info.GetBoolean("_roleForAnonymousReturnsNewIfNotFound"); + _alwaysFetchRoleForAnonymous = info.GetBoolean("_alwaysFetchRoleForAnonymous"); + _alreadyFetchedRoleForAnonymous = info.GetBoolean("_alreadyFetchedRoleForAnonymous"); + _roleForNewUser = (RoleEntity)info.GetValue("_roleForNewUser", typeof(RoleEntity)); + if(_roleForNewUser!=null) + { + _roleForNewUser.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _roleForNewUserReturnsNewIfNotFound = info.GetBoolean("_roleForNewUserReturnsNewIfNotFound"); + _alwaysFetchRoleForNewUser = info.GetBoolean("_alwaysFetchRoleForNewUser"); + _alreadyFetchedRoleForNewUser = info.GetBoolean("_alreadyFetchedRoleForNewUser"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((SystemDataFieldIndex)fieldIndex) + { + case SystemDataFieldIndex.DefaultRoleNewUser: + DesetupSyncRoleForNewUser(true, false); + _alreadyFetchedRoleForNewUser = false; + break; + case SystemDataFieldIndex.AnonymousRole: + DesetupSyncRoleForAnonymous(true, false); + _alreadyFetchedRoleForAnonymous = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedRoleForAnonymous = (_roleForAnonymous != null); + _alreadyFetchedRoleForNewUser = (_roleForNewUser != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return SystemDataEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "RoleForAnonymous": + toReturn.Add(SystemDataEntity.Relations.RoleEntityUsingAnonymousRole); + break; + case "RoleForNewUser": + toReturn.Add(SystemDataEntity.Relations.RoleEntityUsingDefaultRoleNewUser); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_roleForAnonymous", (!this.MarkedForDeletion?_roleForAnonymous:null)); + info.AddValue("_roleForAnonymousReturnsNewIfNotFound", _roleForAnonymousReturnsNewIfNotFound); + info.AddValue("_alwaysFetchRoleForAnonymous", _alwaysFetchRoleForAnonymous); + info.AddValue("_alreadyFetchedRoleForAnonymous", _alreadyFetchedRoleForAnonymous); + info.AddValue("_roleForNewUser", (!this.MarkedForDeletion?_roleForNewUser:null)); + info.AddValue("_roleForNewUserReturnsNewIfNotFound", _roleForNewUserReturnsNewIfNotFound); + info.AddValue("_alwaysFetchRoleForNewUser", _alwaysFetchRoleForNewUser); + info.AddValue("_alreadyFetchedRoleForNewUser", _alreadyFetchedRoleForNewUser); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "RoleForAnonymous": + _alreadyFetchedRoleForAnonymous = true; + this.RoleForAnonymous = (RoleEntity)entity; + break; + case "RoleForNewUser": + _alreadyFetchedRoleForNewUser = true; + this.RoleForNewUser = (RoleEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "RoleForAnonymous": + SetupSyncRoleForAnonymous(relatedEntity); + break; + case "RoleForNewUser": + SetupSyncRoleForNewUser(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "RoleForAnonymous": + DesetupSyncRoleForAnonymous(false, true); + break; + case "RoleForNewUser": + DesetupSyncRoleForNewUser(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_roleForAnonymous!=null) + { + toReturn.Add(_roleForAnonymous); + } + if(_roleForNewUser!=null) + { + toReturn.Add(_roleForNewUser); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SystemData which data should be fetched into this SystemData object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 iD) + { + return FetchUsingPK(iD, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SystemData which data should be fetched into this SystemData object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 iD, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(iD, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SystemData which data should be fetched into this SystemData object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 iD, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(iD, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for SystemData which data should be fetched into this SystemData object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 iD, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(iD, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.ID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(SystemDataFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(SystemDataFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new SystemDataRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public RoleEntity GetSingleRoleForAnonymous() + { + return GetSingleRoleForAnonymous(false); + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public virtual RoleEntity GetSingleRoleForAnonymous(bool forceFetch) + { + if( ( !_alreadyFetchedRoleForAnonymous || forceFetch || _alwaysFetchRoleForAnonymous) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(SystemDataEntity.Relations.RoleEntityUsingAnonymousRole); + + RoleEntity newEntity = new RoleEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.AnonymousRole); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (RoleEntity)base.ActiveContext.Get(newEntity); + } + this.RoleForAnonymous = newEntity; + } + else + { + if(_roleForAnonymousReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_roleForAnonymous == null))) + { + this.RoleForAnonymous = newEntity; + } + } + else + { + this.RoleForAnonymous = null; + } + } + _alreadyFetchedRoleForAnonymous = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _roleForAnonymous; + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public RoleEntity GetSingleRoleForNewUser() + { + return GetSingleRoleForNewUser(false); + } + + /// Retrieves the related entity of type 'RoleEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'RoleEntity' which is related to this entity. + public virtual RoleEntity GetSingleRoleForNewUser(bool forceFetch) + { + if( ( !_alreadyFetchedRoleForNewUser || forceFetch || _alwaysFetchRoleForNewUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(SystemDataEntity.Relations.RoleEntityUsingDefaultRoleNewUser); + + RoleEntity newEntity = new RoleEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.DefaultRoleNewUser); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (RoleEntity)base.ActiveContext.Get(newEntity); + } + this.RoleForNewUser = newEntity; + } + else + { + if(_roleForNewUserReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_roleForNewUser == null))) + { + this.RoleForNewUser = newEntity; + } + } + else + { + this.RoleForNewUser = null; + } + } + _alreadyFetchedRoleForNewUser = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _roleForNewUser; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + SystemDataDAO dao = (SystemDataDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_roleForAnonymous!=null) + { + _roleForAnonymous.ActiveContext = base.ActiveContext; + } + if(_roleForNewUser!=null) + { + _roleForNewUser.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + SystemDataDAO dao = (SystemDataDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + SystemDataDAO dao = (SystemDataDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.SystemDataEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("RoleForAnonymous", _roleForAnonymous); + toReturn.Add("RoleForNewUser", _roleForNewUser); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for SystemData which data should be fetched into this SystemData object + /// The validator object for this SystemDataEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 iD, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(iD, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _roleForAnonymous = null; + _roleForAnonymousReturnsNewIfNotFound = true; + _alwaysFetchRoleForAnonymous = false; + _alreadyFetchedRoleForAnonymous = false; + _roleForNewUser = null; + _roleForNewUserReturnsNewIfNotFound = true; + _alwaysFetchRoleForNewUser = false; + _alreadyFetchedRoleForNewUser = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("DefaultRoleNewUser", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AnonymousRole", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("DefaultUserTitleNewUser", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("HoursThresholdForActiveThreads", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("PageSizeSearchResults", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MinNumberOfThreadsToFetch", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MinNumberOfNonStickyVisibleThreads", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("SendReplyNotifications", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _roleForAnonymous + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncRoleForAnonymous(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _roleForAnonymous, new PropertyChangedEventHandler( OnRoleForAnonymousPropertyChanged ), "RoleForAnonymous", SystemDataEntity.Relations.RoleEntityUsingAnonymousRole, true, signalRelatedEntity, "SystemDataAnonymousRole", resetFKFields, new int[] { (int)SystemDataFieldIndex.AnonymousRole } ); + _roleForAnonymous = null; + } + + /// setups the sync logic for member _roleForAnonymous + /// Instance to set as the related entity of type entityType + private void SetupSyncRoleForAnonymous(IEntity relatedEntity) + { + if(_roleForAnonymous!=relatedEntity) + { + DesetupSyncRoleForAnonymous(true, true); + _roleForAnonymous = (RoleEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _roleForAnonymous, new PropertyChangedEventHandler( OnRoleForAnonymousPropertyChanged ), "RoleForAnonymous", SystemDataEntity.Relations.RoleEntityUsingAnonymousRole, true, ref _alreadyFetchedRoleForAnonymous, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnRoleForAnonymousPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _roleForNewUser + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncRoleForNewUser(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _roleForNewUser, new PropertyChangedEventHandler( OnRoleForNewUserPropertyChanged ), "RoleForNewUser", SystemDataEntity.Relations.RoleEntityUsingDefaultRoleNewUser, true, signalRelatedEntity, "SystemDataDefaultRoleNewUser", resetFKFields, new int[] { (int)SystemDataFieldIndex.DefaultRoleNewUser } ); + _roleForNewUser = null; + } + + /// setups the sync logic for member _roleForNewUser + /// Instance to set as the related entity of type entityType + private void SetupSyncRoleForNewUser(IEntity relatedEntity) + { + if(_roleForNewUser!=relatedEntity) + { + DesetupSyncRoleForNewUser(true, true); + _roleForNewUser = (RoleEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _roleForNewUser, new PropertyChangedEventHandler( OnRoleForNewUserPropertyChanged ), "RoleForNewUser", SystemDataEntity.Relations.RoleEntityUsingDefaultRoleNewUser, true, ref _alreadyFetchedRoleForNewUser, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnRoleForNewUserPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for SystemData which data should be fetched into this SystemData object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 iD, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)SystemDataFieldIndex.ID].ForcedCurrentValueWrite(iD); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateSystemDataDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new SystemDataEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static SystemDataRelations Relations + { + get { return new SystemDataRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoleForAnonymous + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), + (IEntityRelation)GetRelationsForField("RoleForAnonymous")[0], (int)SD.HnD.DAL.EntityType.SystemDataEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, null, "RoleForAnonymous", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoleForNewUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), + (IEntityRelation)GetRelationsForField("RoleForNewUser")[0], (int)SD.HnD.DAL.EntityType.SystemDataEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, null, "RoleForNewUser", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "SystemDataEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return SystemDataEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return SystemDataEntity.FieldsCustomProperties;} + } + + /// The ID property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."ID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 ID + { + get { return (System.Int32)GetValue((int)SystemDataFieldIndex.ID, true); } + set { SetValue((int)SystemDataFieldIndex.ID, value, true); } + } + /// The DefaultRoleNewUser property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."DefaultRoleNewUser"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 DefaultRoleNewUser + { + get { return (System.Int32)GetValue((int)SystemDataFieldIndex.DefaultRoleNewUser, true); } + set { SetValue((int)SystemDataFieldIndex.DefaultRoleNewUser, value, true); } + } + /// The AnonymousRole property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."AnonymousRole"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 AnonymousRole + { + get { return (System.Int32)GetValue((int)SystemDataFieldIndex.AnonymousRole, true); } + set { SetValue((int)SystemDataFieldIndex.AnonymousRole, value, true); } + } + /// The DefaultUserTitleNewUser property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."DefaultUserTitleNewUser"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 DefaultUserTitleNewUser + { + get { return (System.Int32)GetValue((int)SystemDataFieldIndex.DefaultUserTitleNewUser, true); } + set { SetValue((int)SystemDataFieldIndex.DefaultUserTitleNewUser, value, true); } + } + /// The HoursThresholdForActiveThreads property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."HoursThresholdForActiveThreads"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int16 HoursThresholdForActiveThreads + { + get { return (System.Int16)GetValue((int)SystemDataFieldIndex.HoursThresholdForActiveThreads, true); } + set { SetValue((int)SystemDataFieldIndex.HoursThresholdForActiveThreads, value, true); } + } + /// The PageSizeSearchResults property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."PageSizeSearchResults"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int16 PageSizeSearchResults + { + get { return (System.Int16)GetValue((int)SystemDataFieldIndex.PageSizeSearchResults, true); } + set { SetValue((int)SystemDataFieldIndex.PageSizeSearchResults, value, true); } + } + /// The MinNumberOfThreadsToFetch property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."MinNumberOfThreadsToFetch"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int16 MinNumberOfThreadsToFetch + { + get { return (System.Int16)GetValue((int)SystemDataFieldIndex.MinNumberOfThreadsToFetch, true); } + set { SetValue((int)SystemDataFieldIndex.MinNumberOfThreadsToFetch, value, true); } + } + /// The MinNumberOfNonStickyVisibleThreads property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."MinNumberOfNonStickyVisibleThreads"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int16 MinNumberOfNonStickyVisibleThreads + { + get { return (System.Int16)GetValue((int)SystemDataFieldIndex.MinNumberOfNonStickyVisibleThreads, true); } + set { SetValue((int)SystemDataFieldIndex.MinNumberOfNonStickyVisibleThreads, value, true); } + } + /// The SendReplyNotifications property of the Entity SystemData

+ ///
+ /// Mapped on table field: "SystemData"."SendReplyNotifications"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean SendReplyNotifications + { + get { return (System.Boolean)GetValue((int)SystemDataFieldIndex.SendReplyNotifications, true); } + set { SetValue((int)SystemDataFieldIndex.SendReplyNotifications, value, true); } + } + + + + /// Gets / sets related entity of type 'RoleEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleRoleForAnonymous()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual RoleEntity RoleForAnonymous + { + get { return GetSingleRoleForAnonymous(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncRoleForAnonymous(value); + } + else + { + if(value==null) + { + if(_roleForAnonymous != null) + { + _roleForAnonymous.UnsetRelatedEntity(this, "SystemDataAnonymousRole"); + } + } + else + { + if(_roleForAnonymous!=value) + { + ((IEntity)value).SetRelatedEntity(this, "SystemDataAnonymousRole"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for RoleForAnonymous. When set to true, RoleForAnonymous is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RoleForAnonymous is accessed. You can always execute + /// a forced fetch by calling GetSingleRoleForAnonymous(true). + [Browsable(false)] + public bool AlwaysFetchRoleForAnonymous + { + get { return _alwaysFetchRoleForAnonymous; } + set { _alwaysFetchRoleForAnonymous = value; } + } + + /// Gets / Sets the lazy loading flag if the property RoleForAnonymous already has been fetched. Setting this property to false when RoleForAnonymous has been fetched + /// will set RoleForAnonymous to null as well. Setting this property to true while RoleForAnonymous hasn't been fetched disables lazy loading for RoleForAnonymous + [Browsable(false)] + public bool AlreadyFetchedRoleForAnonymous + { + get { return _alreadyFetchedRoleForAnonymous;} + set + { + if(_alreadyFetchedRoleForAnonymous && !value) + { + this.RoleForAnonymous = null; + } + _alreadyFetchedRoleForAnonymous = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property RoleForAnonymous is not found + /// in the database. When set to true, RoleForAnonymous will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool RoleForAnonymousReturnsNewIfNotFound + { + get { return _roleForAnonymousReturnsNewIfNotFound; } + set { _roleForAnonymousReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'RoleEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleRoleForNewUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual RoleEntity RoleForNewUser + { + get { return GetSingleRoleForNewUser(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncRoleForNewUser(value); + } + else + { + if(value==null) + { + if(_roleForNewUser != null) + { + _roleForNewUser.UnsetRelatedEntity(this, "SystemDataDefaultRoleNewUser"); + } + } + else + { + if(_roleForNewUser!=value) + { + ((IEntity)value).SetRelatedEntity(this, "SystemDataDefaultRoleNewUser"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for RoleForNewUser. When set to true, RoleForNewUser is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RoleForNewUser is accessed. You can always execute + /// a forced fetch by calling GetSingleRoleForNewUser(true). + [Browsable(false)] + public bool AlwaysFetchRoleForNewUser + { + get { return _alwaysFetchRoleForNewUser; } + set { _alwaysFetchRoleForNewUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property RoleForNewUser already has been fetched. Setting this property to false when RoleForNewUser has been fetched + /// will set RoleForNewUser to null as well. Setting this property to true while RoleForNewUser hasn't been fetched disables lazy loading for RoleForNewUser + [Browsable(false)] + public bool AlreadyFetchedRoleForNewUser + { + get { return _alreadyFetchedRoleForNewUser;} + set + { + if(_alreadyFetchedRoleForNewUser && !value) + { + this.RoleForNewUser = null; + } + _alreadyFetchedRoleForNewUser = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property RoleForNewUser is not found + /// in the database. When set to true, RoleForNewUser will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool RoleForNewUserReturnsNewIfNotFound + { + get { return _roleForNewUserReturnsNewIfNotFound; } + set { _roleForNewUserReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.SystemDataEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/ThreadEntityBase.cs b/DAL/EntityBaseClasses/ThreadEntityBase.cs new file mode 100644 index 0000000..ba7687f --- /dev/null +++ b/DAL/EntityBaseClasses/ThreadEntityBase.cs @@ -0,0 +1,2282 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'Thread'.

+ /// + ///
+ [Serializable] + public abstract partial class ThreadEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection _auditDataThreadRelated; + private bool _alwaysFetchAuditDataThreadRelated, _alreadyFetchedAuditDataThreadRelated; + private SD.HnD.DAL.CollectionClasses.BookmarkCollection _presentInBookmarks; + private bool _alwaysFetchPresentInBookmarks, _alreadyFetchedPresentInBookmarks; + private SD.HnD.DAL.CollectionClasses.MessageCollection _messages; + private bool _alwaysFetchMessages, _alreadyFetchedMessages; + private SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection _threadSubscription; + private bool _alwaysFetchThreadSubscription, _alreadyFetchedThreadSubscription; + private SD.HnD.DAL.CollectionClasses.UserCollection _usersWhoSubscribedThread; + private bool _alwaysFetchUsersWhoSubscribedThread, _alreadyFetchedUsersWhoSubscribedThread; + private SD.HnD.DAL.CollectionClasses.UserCollection _usersWhoPostedInThread; + private bool _alwaysFetchUsersWhoPostedInThread, _alreadyFetchedUsersWhoPostedInThread; + private SD.HnD.DAL.CollectionClasses.UserCollection _usersWhoBookmarkedThread; + private bool _alwaysFetchUsersWhoBookmarkedThread, _alreadyFetchedUsersWhoBookmarkedThread; + private ForumEntity _forum; + private bool _alwaysFetchForum, _alreadyFetchedForum, _forumReturnsNewIfNotFound; + private UserEntity _userWhoStartedThread; + private bool _alwaysFetchUserWhoStartedThread, _alreadyFetchedUserWhoStartedThread, _userWhoStartedThreadReturnsNewIfNotFound; + private SupportQueueThreadEntity _supportQueueThread; + private bool _alwaysFetchSupportQueueThread, _alreadyFetchedSupportQueueThread, _supportQueueThreadReturnsNewIfNotFound; + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name Forum + public static readonly string Forum = "Forum"; + /// Member name UserWhoStartedThread + public static readonly string UserWhoStartedThread = "UserWhoStartedThread"; + /// Member name AuditDataThreadRelated + public static readonly string AuditDataThreadRelated = "AuditDataThreadRelated"; + /// Member name PresentInBookmarks + public static readonly string PresentInBookmarks = "PresentInBookmarks"; + /// Member name Messages + public static readonly string Messages = "Messages"; + /// Member name ThreadSubscription + public static readonly string ThreadSubscription = "ThreadSubscription"; + /// Member name UsersWhoSubscribedThread + public static readonly string UsersWhoSubscribedThread = "UsersWhoSubscribedThread"; + /// Member name UsersWhoPostedInThread + public static readonly string UsersWhoPostedInThread = "UsersWhoPostedInThread"; + /// Member name UsersWhoBookmarkedThread + public static readonly string UsersWhoBookmarkedThread = "UsersWhoBookmarkedThread"; + /// Member name SupportQueueThread + public static readonly string SupportQueueThread = "SupportQueueThread"; + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static ThreadEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public ThreadEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for Thread which data should be fetched into this Thread object + public ThreadEntityBase(System.Int32 threadID) + { + InitClassFetch(threadID, null, null); + } + + /// CTor + /// PK value for Thread which data should be fetched into this Thread object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ThreadEntityBase(System.Int32 threadID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(threadID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for Thread which data should be fetched into this Thread object + /// The custom validator object for this ThreadEntity + public ThreadEntityBase(System.Int32 threadID, IValidator validator) + { + InitClassFetch(threadID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected ThreadEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _auditDataThreadRelated = (SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection)info.GetValue("_auditDataThreadRelated", typeof(SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection)); + _alwaysFetchAuditDataThreadRelated = info.GetBoolean("_alwaysFetchAuditDataThreadRelated"); + _alreadyFetchedAuditDataThreadRelated = info.GetBoolean("_alreadyFetchedAuditDataThreadRelated"); + _presentInBookmarks = (SD.HnD.DAL.CollectionClasses.BookmarkCollection)info.GetValue("_presentInBookmarks", typeof(SD.HnD.DAL.CollectionClasses.BookmarkCollection)); + _alwaysFetchPresentInBookmarks = info.GetBoolean("_alwaysFetchPresentInBookmarks"); + _alreadyFetchedPresentInBookmarks = info.GetBoolean("_alreadyFetchedPresentInBookmarks"); + _messages = (SD.HnD.DAL.CollectionClasses.MessageCollection)info.GetValue("_messages", typeof(SD.HnD.DAL.CollectionClasses.MessageCollection)); + _alwaysFetchMessages = info.GetBoolean("_alwaysFetchMessages"); + _alreadyFetchedMessages = info.GetBoolean("_alreadyFetchedMessages"); + _threadSubscription = (SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection)info.GetValue("_threadSubscription", typeof(SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection)); + _alwaysFetchThreadSubscription = info.GetBoolean("_alwaysFetchThreadSubscription"); + _alreadyFetchedThreadSubscription = info.GetBoolean("_alreadyFetchedThreadSubscription"); + _usersWhoSubscribedThread = (SD.HnD.DAL.CollectionClasses.UserCollection)info.GetValue("_usersWhoSubscribedThread", typeof(SD.HnD.DAL.CollectionClasses.UserCollection)); + _alwaysFetchUsersWhoSubscribedThread = info.GetBoolean("_alwaysFetchUsersWhoSubscribedThread"); + _alreadyFetchedUsersWhoSubscribedThread = info.GetBoolean("_alreadyFetchedUsersWhoSubscribedThread"); + _usersWhoPostedInThread = (SD.HnD.DAL.CollectionClasses.UserCollection)info.GetValue("_usersWhoPostedInThread", typeof(SD.HnD.DAL.CollectionClasses.UserCollection)); + _alwaysFetchUsersWhoPostedInThread = info.GetBoolean("_alwaysFetchUsersWhoPostedInThread"); + _alreadyFetchedUsersWhoPostedInThread = info.GetBoolean("_alreadyFetchedUsersWhoPostedInThread"); + _usersWhoBookmarkedThread = (SD.HnD.DAL.CollectionClasses.UserCollection)info.GetValue("_usersWhoBookmarkedThread", typeof(SD.HnD.DAL.CollectionClasses.UserCollection)); + _alwaysFetchUsersWhoBookmarkedThread = info.GetBoolean("_alwaysFetchUsersWhoBookmarkedThread"); + _alreadyFetchedUsersWhoBookmarkedThread = info.GetBoolean("_alreadyFetchedUsersWhoBookmarkedThread"); + _forum = (ForumEntity)info.GetValue("_forum", typeof(ForumEntity)); + if(_forum!=null) + { + _forum.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _forumReturnsNewIfNotFound = info.GetBoolean("_forumReturnsNewIfNotFound"); + _alwaysFetchForum = info.GetBoolean("_alwaysFetchForum"); + _alreadyFetchedForum = info.GetBoolean("_alreadyFetchedForum"); + _userWhoStartedThread = (UserEntity)info.GetValue("_userWhoStartedThread", typeof(UserEntity)); + if(_userWhoStartedThread!=null) + { + _userWhoStartedThread.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _userWhoStartedThreadReturnsNewIfNotFound = info.GetBoolean("_userWhoStartedThreadReturnsNewIfNotFound"); + _alwaysFetchUserWhoStartedThread = info.GetBoolean("_alwaysFetchUserWhoStartedThread"); + _alreadyFetchedUserWhoStartedThread = info.GetBoolean("_alreadyFetchedUserWhoStartedThread"); + _supportQueueThread = (SupportQueueThreadEntity)info.GetValue("_supportQueueThread", typeof(SupportQueueThreadEntity)); + if(_supportQueueThread!=null) + { + _supportQueueThread.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _supportQueueThreadReturnsNewIfNotFound = info.GetBoolean("_supportQueueThreadReturnsNewIfNotFound"); + _alwaysFetchSupportQueueThread = info.GetBoolean("_alwaysFetchSupportQueueThread"); + _alreadyFetchedSupportQueueThread = info.GetBoolean("_alreadyFetchedSupportQueueThread"); + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((ThreadFieldIndex)fieldIndex) + { + case ThreadFieldIndex.ForumID: + DesetupSyncForum(true, false); + _alreadyFetchedForum = false; + break; + case ThreadFieldIndex.StartedByUserID: + DesetupSyncUserWhoStartedThread(true, false); + _alreadyFetchedUserWhoStartedThread = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedAuditDataThreadRelated = (_auditDataThreadRelated.Count > 0); + _alreadyFetchedPresentInBookmarks = (_presentInBookmarks.Count > 0); + _alreadyFetchedMessages = (_messages.Count > 0); + _alreadyFetchedThreadSubscription = (_threadSubscription.Count > 0); + _alreadyFetchedUsersWhoSubscribedThread = (_usersWhoSubscribedThread.Count > 0); + _alreadyFetchedUsersWhoPostedInThread = (_usersWhoPostedInThread.Count > 0); + _alreadyFetchedUsersWhoBookmarkedThread = (_usersWhoBookmarkedThread.Count > 0); + _alreadyFetchedForum = (_forum != null); + _alreadyFetchedUserWhoStartedThread = (_userWhoStartedThread != null); + _alreadyFetchedSupportQueueThread = (_supportQueueThread != null); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return ThreadEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "Forum": + toReturn.Add(ThreadEntity.Relations.ForumEntityUsingForumID); + break; + case "UserWhoStartedThread": + toReturn.Add(ThreadEntity.Relations.UserEntityUsingStartedByUserID); + break; + case "AuditDataThreadRelated": + toReturn.Add(ThreadEntity.Relations.AuditDataThreadRelatedEntityUsingThreadID); + break; + case "PresentInBookmarks": + toReturn.Add(ThreadEntity.Relations.BookmarkEntityUsingThreadID); + break; + case "Messages": + toReturn.Add(ThreadEntity.Relations.MessageEntityUsingThreadID); + break; + case "ThreadSubscription": + toReturn.Add(ThreadEntity.Relations.ThreadSubscriptionEntityUsingThreadID); + break; + case "UsersWhoSubscribedThread": + toReturn.Add(ThreadEntity.Relations.ThreadSubscriptionEntityUsingThreadID, "ThreadEntity__", "ThreadSubscription_", JoinHint.None); + toReturn.Add(ThreadSubscriptionEntity.Relations.UserEntityUsingUserID, "ThreadSubscription_", string.Empty, JoinHint.None); + break; + case "UsersWhoPostedInThread": + toReturn.Add(ThreadEntity.Relations.MessageEntityUsingThreadID, "ThreadEntity__", "Message_", JoinHint.None); + toReturn.Add(MessageEntity.Relations.UserEntityUsingPostedByUserID, "Message_", string.Empty, JoinHint.None); + break; + case "UsersWhoBookmarkedThread": + toReturn.Add(ThreadEntity.Relations.BookmarkEntityUsingThreadID, "ThreadEntity__", "Bookmark_", JoinHint.None); + toReturn.Add(BookmarkEntity.Relations.UserEntityUsingUserID, "Bookmark_", string.Empty, JoinHint.None); + break; + case "SupportQueueThread": + toReturn.Add(ThreadEntity.Relations.SupportQueueThreadEntityUsingThreadID); + break; + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_auditDataThreadRelated", (!this.MarkedForDeletion?_auditDataThreadRelated:null)); + info.AddValue("_alwaysFetchAuditDataThreadRelated", _alwaysFetchAuditDataThreadRelated); + info.AddValue("_alreadyFetchedAuditDataThreadRelated", _alreadyFetchedAuditDataThreadRelated); + info.AddValue("_presentInBookmarks", (!this.MarkedForDeletion?_presentInBookmarks:null)); + info.AddValue("_alwaysFetchPresentInBookmarks", _alwaysFetchPresentInBookmarks); + info.AddValue("_alreadyFetchedPresentInBookmarks", _alreadyFetchedPresentInBookmarks); + info.AddValue("_messages", (!this.MarkedForDeletion?_messages:null)); + info.AddValue("_alwaysFetchMessages", _alwaysFetchMessages); + info.AddValue("_alreadyFetchedMessages", _alreadyFetchedMessages); + info.AddValue("_threadSubscription", (!this.MarkedForDeletion?_threadSubscription:null)); + info.AddValue("_alwaysFetchThreadSubscription", _alwaysFetchThreadSubscription); + info.AddValue("_alreadyFetchedThreadSubscription", _alreadyFetchedThreadSubscription); + info.AddValue("_usersWhoSubscribedThread", (!this.MarkedForDeletion?_usersWhoSubscribedThread:null)); + info.AddValue("_alwaysFetchUsersWhoSubscribedThread", _alwaysFetchUsersWhoSubscribedThread); + info.AddValue("_alreadyFetchedUsersWhoSubscribedThread", _alreadyFetchedUsersWhoSubscribedThread); + info.AddValue("_usersWhoPostedInThread", (!this.MarkedForDeletion?_usersWhoPostedInThread:null)); + info.AddValue("_alwaysFetchUsersWhoPostedInThread", _alwaysFetchUsersWhoPostedInThread); + info.AddValue("_alreadyFetchedUsersWhoPostedInThread", _alreadyFetchedUsersWhoPostedInThread); + info.AddValue("_usersWhoBookmarkedThread", (!this.MarkedForDeletion?_usersWhoBookmarkedThread:null)); + info.AddValue("_alwaysFetchUsersWhoBookmarkedThread", _alwaysFetchUsersWhoBookmarkedThread); + info.AddValue("_alreadyFetchedUsersWhoBookmarkedThread", _alreadyFetchedUsersWhoBookmarkedThread); + info.AddValue("_forum", (!this.MarkedForDeletion?_forum:null)); + info.AddValue("_forumReturnsNewIfNotFound", _forumReturnsNewIfNotFound); + info.AddValue("_alwaysFetchForum", _alwaysFetchForum); + info.AddValue("_alreadyFetchedForum", _alreadyFetchedForum); + info.AddValue("_userWhoStartedThread", (!this.MarkedForDeletion?_userWhoStartedThread:null)); + info.AddValue("_userWhoStartedThreadReturnsNewIfNotFound", _userWhoStartedThreadReturnsNewIfNotFound); + info.AddValue("_alwaysFetchUserWhoStartedThread", _alwaysFetchUserWhoStartedThread); + info.AddValue("_alreadyFetchedUserWhoStartedThread", _alreadyFetchedUserWhoStartedThread); + info.AddValue("_supportQueueThread", (!this.MarkedForDeletion?_supportQueueThread:null)); + info.AddValue("_supportQueueThreadReturnsNewIfNotFound", _supportQueueThreadReturnsNewIfNotFound); + info.AddValue("_alwaysFetchSupportQueueThread", _alwaysFetchSupportQueueThread); + info.AddValue("_alreadyFetchedSupportQueueThread", _alreadyFetchedSupportQueueThread); + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "Forum": + _alreadyFetchedForum = true; + this.Forum = (ForumEntity)entity; + break; + case "UserWhoStartedThread": + _alreadyFetchedUserWhoStartedThread = true; + this.UserWhoStartedThread = (UserEntity)entity; + break; + case "AuditDataThreadRelated": + _alreadyFetchedAuditDataThreadRelated = true; + if(entity!=null) + { + this.AuditDataThreadRelated.Add((AuditDataThreadRelatedEntity)entity); + } + break; + case "PresentInBookmarks": + _alreadyFetchedPresentInBookmarks = true; + if(entity!=null) + { + this.PresentInBookmarks.Add((BookmarkEntity)entity); + } + break; + case "Messages": + _alreadyFetchedMessages = true; + if(entity!=null) + { + this.Messages.Add((MessageEntity)entity); + } + break; + case "ThreadSubscription": + _alreadyFetchedThreadSubscription = true; + if(entity!=null) + { + this.ThreadSubscription.Add((ThreadSubscriptionEntity)entity); + } + break; + case "UsersWhoSubscribedThread": + _alreadyFetchedUsersWhoSubscribedThread = true; + if(entity!=null) + { + this.UsersWhoSubscribedThread.Add((UserEntity)entity); + } + break; + case "UsersWhoPostedInThread": + _alreadyFetchedUsersWhoPostedInThread = true; + if(entity!=null) + { + this.UsersWhoPostedInThread.Add((UserEntity)entity); + } + break; + case "UsersWhoBookmarkedThread": + _alreadyFetchedUsersWhoBookmarkedThread = true; + if(entity!=null) + { + this.UsersWhoBookmarkedThread.Add((UserEntity)entity); + } + break; + case "SupportQueueThread": + _alreadyFetchedSupportQueueThread = true; + this.SupportQueueThread = (SupportQueueThreadEntity)entity; + break; + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "Forum": + SetupSyncForum(relatedEntity); + break; + case "UserWhoStartedThread": + SetupSyncUserWhoStartedThread(relatedEntity); + break; + case "AuditDataThreadRelated": + _auditDataThreadRelated.Add((AuditDataThreadRelatedEntity)relatedEntity); + break; + case "PresentInBookmarks": + _presentInBookmarks.Add((BookmarkEntity)relatedEntity); + break; + case "Messages": + _messages.Add((MessageEntity)relatedEntity); + break; + case "ThreadSubscription": + _threadSubscription.Add((ThreadSubscriptionEntity)relatedEntity); + break; + case "SupportQueueThread": + SetupSyncSupportQueueThread(relatedEntity); + break; + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "Forum": + DesetupSyncForum(false, true); + break; + case "UserWhoStartedThread": + DesetupSyncUserWhoStartedThread(false, true); + break; + case "AuditDataThreadRelated": + base.PerformRelatedEntityRemoval(_auditDataThreadRelated, relatedEntity, signalRelatedEntityManyToOne); + break; + case "PresentInBookmarks": + base.PerformRelatedEntityRemoval(_presentInBookmarks, relatedEntity, signalRelatedEntityManyToOne); + break; + case "Messages": + base.PerformRelatedEntityRemoval(_messages, relatedEntity, signalRelatedEntityManyToOne); + break; + case "ThreadSubscription": + base.PerformRelatedEntityRemoval(_threadSubscription, relatedEntity, signalRelatedEntityManyToOne); + break; + case "SupportQueueThread": + DesetupSyncSupportQueueThread(false, true); + break; + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + if(_supportQueueThread!=null) + { + toReturn.Add(_supportQueueThread); + } + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_forum!=null) + { + toReturn.Add(_forum); + } + if(_userWhoStartedThread!=null) + { + toReturn.Add(_userWhoStartedThread); + } + + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_auditDataThreadRelated); + toReturn.Add(_presentInBookmarks); + toReturn.Add(_messages); + toReturn.Add(_threadSubscription); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Thread which data should be fetched into this Thread object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 threadID) + { + return FetchUsingPK(threadID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Thread which data should be fetched into this Thread object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 threadID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(threadID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Thread which data should be fetched into this Thread object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(threadID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for Thread which data should be fetched into this Thread object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(threadID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.ThreadID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(ThreadFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(ThreadFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new ThreadRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'AuditDataThreadRelatedEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'AuditDataThreadRelatedEntity' + public SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection GetMultiAuditDataThreadRelated(bool forceFetch) + { + return GetMultiAuditDataThreadRelated(forceFetch, _auditDataThreadRelated.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AuditDataThreadRelatedEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'AuditDataThreadRelatedEntity' + public SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection GetMultiAuditDataThreadRelated(bool forceFetch, IPredicateExpression filter) + { + return GetMultiAuditDataThreadRelated(forceFetch, _auditDataThreadRelated.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'AuditDataThreadRelatedEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection GetMultiAuditDataThreadRelated(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiAuditDataThreadRelated(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AuditDataThreadRelatedEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection GetMultiAuditDataThreadRelated(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedAuditDataThreadRelated || forceFetch || _alwaysFetchAuditDataThreadRelated) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_auditDataThreadRelated.ParticipatesInTransaction) + { + base.Transaction.Add(_auditDataThreadRelated); + } + } + _auditDataThreadRelated.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _auditDataThreadRelated.EntityFactoryToUse = entityFactoryToUse; + } + _auditDataThreadRelated.GetMultiManyToOne(null, this, null, filter); + _auditDataThreadRelated.SuppressClearInGetMulti=false; + _alreadyFetchedAuditDataThreadRelated = true; + } + return _auditDataThreadRelated; + } + + /// Sets the collection parameters for the collection for 'AuditDataThreadRelated'. These settings will be taken into account + /// when the property AuditDataThreadRelated is requested or GetMultiAuditDataThreadRelated is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersAuditDataThreadRelated(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _auditDataThreadRelated.SortClauses=sortClauses; + _auditDataThreadRelated.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'BookmarkEntity' + public SD.HnD.DAL.CollectionClasses.BookmarkCollection GetMultiPresentInBookmarks(bool forceFetch) + { + return GetMultiPresentInBookmarks(forceFetch, _presentInBookmarks.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'BookmarkEntity' + public SD.HnD.DAL.CollectionClasses.BookmarkCollection GetMultiPresentInBookmarks(bool forceFetch, IPredicateExpression filter) + { + return GetMultiPresentInBookmarks(forceFetch, _presentInBookmarks.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.BookmarkCollection GetMultiPresentInBookmarks(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiPresentInBookmarks(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.BookmarkCollection GetMultiPresentInBookmarks(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedPresentInBookmarks || forceFetch || _alwaysFetchPresentInBookmarks) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_presentInBookmarks.ParticipatesInTransaction) + { + base.Transaction.Add(_presentInBookmarks); + } + } + _presentInBookmarks.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _presentInBookmarks.EntityFactoryToUse = entityFactoryToUse; + } + _presentInBookmarks.GetMultiManyToOne(this, null, filter); + _presentInBookmarks.SuppressClearInGetMulti=false; + _alreadyFetchedPresentInBookmarks = true; + } + return _presentInBookmarks; + } + + /// Sets the collection parameters for the collection for 'PresentInBookmarks'. These settings will be taken into account + /// when the property PresentInBookmarks is requested or GetMultiPresentInBookmarks is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersPresentInBookmarks(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _presentInBookmarks.SortClauses=sortClauses; + _presentInBookmarks.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'MessageEntity' + public SD.HnD.DAL.CollectionClasses.MessageCollection GetMultiMessages(bool forceFetch) + { + return GetMultiMessages(forceFetch, _messages.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'MessageEntity' + public SD.HnD.DAL.CollectionClasses.MessageCollection GetMultiMessages(bool forceFetch, IPredicateExpression filter) + { + return GetMultiMessages(forceFetch, _messages.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.MessageCollection GetMultiMessages(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiMessages(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.MessageCollection GetMultiMessages(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedMessages || forceFetch || _alwaysFetchMessages) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_messages.ParticipatesInTransaction) + { + base.Transaction.Add(_messages); + } + } + _messages.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _messages.EntityFactoryToUse = entityFactoryToUse; + } + _messages.GetMultiManyToOne(this, null, filter); + _messages.SuppressClearInGetMulti=false; + _alreadyFetchedMessages = true; + } + return _messages; + } + + /// Sets the collection parameters for the collection for 'Messages'. These settings will be taken into account + /// when the property Messages is requested or GetMultiMessages is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersMessages(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _messages.SortClauses=sortClauses; + _messages.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ThreadSubscriptionEntity' + public SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection GetMultiThreadSubscription(bool forceFetch) + { + return GetMultiThreadSubscription(forceFetch, _threadSubscription.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ThreadSubscriptionEntity' + public SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection GetMultiThreadSubscription(bool forceFetch, IPredicateExpression filter) + { + return GetMultiThreadSubscription(forceFetch, _threadSubscription.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection GetMultiThreadSubscription(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiThreadSubscription(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection GetMultiThreadSubscription(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedThreadSubscription || forceFetch || _alwaysFetchThreadSubscription) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_threadSubscription.ParticipatesInTransaction) + { + base.Transaction.Add(_threadSubscription); + } + } + _threadSubscription.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _threadSubscription.EntityFactoryToUse = entityFactoryToUse; + } + _threadSubscription.GetMultiManyToOne(this, null, filter); + _threadSubscription.SuppressClearInGetMulti=false; + _alreadyFetchedThreadSubscription = true; + } + return _threadSubscription; + } + + /// Sets the collection parameters for the collection for 'ThreadSubscription'. These settings will be taken into account + /// when the property ThreadSubscription is requested or GetMultiThreadSubscription is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersThreadSubscription(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _threadSubscription.SortClauses=sortClauses; + _threadSubscription.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'UserEntity' + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsersWhoSubscribedThread(bool forceFetch) + { + return GetMultiUsersWhoSubscribedThread(forceFetch, _usersWhoSubscribedThread.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsersWhoSubscribedThread(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedUsersWhoSubscribedThread || forceFetch || _alwaysFetchUsersWhoSubscribedThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_usersWhoSubscribedThread.ParticipatesInTransaction) + { + base.Transaction.Add(_usersWhoSubscribedThread); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(ThreadFields.ThreadID, ComparisonOperator.Equal, this.ThreadID, "ThreadEntity__")); + _usersWhoSubscribedThread.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _usersWhoSubscribedThread.EntityFactoryToUse = entityFactoryToUse; + } + _usersWhoSubscribedThread.GetMulti(filter, GetRelationsForField("UsersWhoSubscribedThread")); + _usersWhoSubscribedThread.SuppressClearInGetMulti=false; + _alreadyFetchedUsersWhoSubscribedThread = true; + } + return _usersWhoSubscribedThread; + } + + /// Sets the collection parameters for the collection for 'UsersWhoSubscribedThread'. These settings will be taken into account + /// when the property UsersWhoSubscribedThread is requested or GetMultiUsersWhoSubscribedThread is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersUsersWhoSubscribedThread(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _usersWhoSubscribedThread.SortClauses=sortClauses; + _usersWhoSubscribedThread.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'UserEntity' + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsersWhoPostedInThread(bool forceFetch) + { + return GetMultiUsersWhoPostedInThread(forceFetch, _usersWhoPostedInThread.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsersWhoPostedInThread(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedUsersWhoPostedInThread || forceFetch || _alwaysFetchUsersWhoPostedInThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_usersWhoPostedInThread.ParticipatesInTransaction) + { + base.Transaction.Add(_usersWhoPostedInThread); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(ThreadFields.ThreadID, ComparisonOperator.Equal, this.ThreadID, "ThreadEntity__")); + _usersWhoPostedInThread.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _usersWhoPostedInThread.EntityFactoryToUse = entityFactoryToUse; + } + _usersWhoPostedInThread.GetMulti(filter, GetRelationsForField("UsersWhoPostedInThread")); + _usersWhoPostedInThread.SuppressClearInGetMulti=false; + _alreadyFetchedUsersWhoPostedInThread = true; + } + return _usersWhoPostedInThread; + } + + /// Sets the collection parameters for the collection for 'UsersWhoPostedInThread'. These settings will be taken into account + /// when the property UsersWhoPostedInThread is requested or GetMultiUsersWhoPostedInThread is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersUsersWhoPostedInThread(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _usersWhoPostedInThread.SortClauses=sortClauses; + _usersWhoPostedInThread.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'UserEntity' + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsersWhoBookmarkedThread(bool forceFetch) + { + return GetMultiUsersWhoBookmarkedThread(forceFetch, _usersWhoBookmarkedThread.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsersWhoBookmarkedThread(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedUsersWhoBookmarkedThread || forceFetch || _alwaysFetchUsersWhoBookmarkedThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_usersWhoBookmarkedThread.ParticipatesInTransaction) + { + base.Transaction.Add(_usersWhoBookmarkedThread); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(ThreadFields.ThreadID, ComparisonOperator.Equal, this.ThreadID, "ThreadEntity__")); + _usersWhoBookmarkedThread.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _usersWhoBookmarkedThread.EntityFactoryToUse = entityFactoryToUse; + } + _usersWhoBookmarkedThread.GetMulti(filter, GetRelationsForField("UsersWhoBookmarkedThread")); + _usersWhoBookmarkedThread.SuppressClearInGetMulti=false; + _alreadyFetchedUsersWhoBookmarkedThread = true; + } + return _usersWhoBookmarkedThread; + } + + /// Sets the collection parameters for the collection for 'UsersWhoBookmarkedThread'. These settings will be taken into account + /// when the property UsersWhoBookmarkedThread is requested or GetMultiUsersWhoBookmarkedThread is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersUsersWhoBookmarkedThread(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _usersWhoBookmarkedThread.SortClauses=sortClauses; + _usersWhoBookmarkedThread.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves the related entity of type 'ForumEntity', using a relation of type 'n:1' + /// A fetched entity of type 'ForumEntity' which is related to this entity. + public ForumEntity GetSingleForum() + { + return GetSingleForum(false); + } + + /// Retrieves the related entity of type 'ForumEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ForumEntity' which is related to this entity. + public virtual ForumEntity GetSingleForum(bool forceFetch) + { + if( ( !_alreadyFetchedForum || forceFetch || _alwaysFetchForum) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ThreadEntity.Relations.ForumEntityUsingForumID); + + ForumEntity newEntity = new ForumEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ForumID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (ForumEntity)base.ActiveContext.Get(newEntity); + } + this.Forum = newEntity; + } + else + { + if(_forumReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_forum == null))) + { + this.Forum = newEntity; + } + } + else + { + this.Forum = null; + } + } + _alreadyFetchedForum = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _forum; + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSingleUserWhoStartedThread() + { + return GetSingleUserWhoStartedThread(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSingleUserWhoStartedThread(bool forceFetch) + { + if( ( !_alreadyFetchedUserWhoStartedThread || forceFetch || _alwaysFetchUserWhoStartedThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ThreadEntity.Relations.UserEntityUsingStartedByUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.StartedByUserID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.UserWhoStartedThread = newEntity; + } + else + { + if(_userWhoStartedThreadReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_userWhoStartedThread == null))) + { + this.UserWhoStartedThread = newEntity; + } + } + else + { + this.UserWhoStartedThread = null; + } + } + _alreadyFetchedUserWhoStartedThread = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _userWhoStartedThread; + } + + /// Retrieves the related entity of type 'SupportQueueThreadEntity', using a relation of type '1:1' + /// A fetched entity of type 'SupportQueueThreadEntity' which is related to this entity. + public SupportQueueThreadEntity GetSingleSupportQueueThread() + { + return GetSingleSupportQueueThread(false); + } + + /// Retrieves the related entity of type 'SupportQueueThreadEntity', using a relation of type '1:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'SupportQueueThreadEntity' which is related to this entity. + public virtual SupportQueueThreadEntity GetSingleSupportQueueThread(bool forceFetch) + { + if( ( !_alreadyFetchedSupportQueueThread || forceFetch || _alwaysFetchSupportQueueThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode ) + { + SupportQueueThreadEntity newEntity = new SupportQueueThreadEntity(); + IEntityRelation relation = ThreadEntity.Relations.SupportQueueThreadEntityUsingThreadID; + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + + bool fetchResult = false; + if(base.CheckIfLazyLoadingShouldOccur(relation)) + { + fetchResult = newEntity.FetchUsingUCThreadID(this.ThreadID); + } + if(!_supportQueueThreadReturnsNewIfNotFound && !fetchResult) + { + this.SupportQueueThread = null; + } + else + { + if((base.ActiveContext!=null)&&fetchResult) + { + newEntity = (SupportQueueThreadEntity)base.ActiveContext.Get(newEntity); + } + this.SupportQueueThread = newEntity; + _alreadyFetchedSupportQueueThread = fetchResult; + } + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _supportQueueThread; + } + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + ThreadDAO dao = (ThreadDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _auditDataThreadRelated.ActiveContext = base.ActiveContext; + _presentInBookmarks.ActiveContext = base.ActiveContext; + _messages.ActiveContext = base.ActiveContext; + _threadSubscription.ActiveContext = base.ActiveContext; + _usersWhoSubscribedThread.ActiveContext = base.ActiveContext; + _usersWhoPostedInThread.ActiveContext = base.ActiveContext; + _usersWhoBookmarkedThread.ActiveContext = base.ActiveContext; + if(_forum!=null) + { + _forum.ActiveContext = base.ActiveContext; + } + if(_userWhoStartedThread!=null) + { + _userWhoStartedThread.ActiveContext = base.ActiveContext; + } + if(_supportQueueThread!=null) + { + _supportQueueThread.ActiveContext = base.ActiveContext; + } + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + ThreadDAO dao = (ThreadDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + ThreadDAO dao = (ThreadDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("Forum", _forum); + toReturn.Add("UserWhoStartedThread", _userWhoStartedThread); + toReturn.Add("AuditDataThreadRelated", _auditDataThreadRelated); + toReturn.Add("PresentInBookmarks", _presentInBookmarks); + toReturn.Add("Messages", _messages); + toReturn.Add("ThreadSubscription", _threadSubscription); + toReturn.Add("UsersWhoSubscribedThread", _usersWhoSubscribedThread); + toReturn.Add("UsersWhoPostedInThread", _usersWhoPostedInThread); + toReturn.Add("UsersWhoBookmarkedThread", _usersWhoBookmarkedThread); + toReturn.Add("SupportQueueThread", _supportQueueThread); + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for Thread which data should be fetched into this Thread object + /// The validator object for this ThreadEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 threadID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(threadID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _auditDataThreadRelated = new SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection(new AuditDataThreadRelatedEntityFactory()); + _auditDataThreadRelated.SetContainingEntityInfo(this, "Thread"); + _alwaysFetchAuditDataThreadRelated = false; + _alreadyFetchedAuditDataThreadRelated = false; + _presentInBookmarks = new SD.HnD.DAL.CollectionClasses.BookmarkCollection(new BookmarkEntityFactory()); + _presentInBookmarks.SetContainingEntityInfo(this, "Thread"); + _alwaysFetchPresentInBookmarks = false; + _alreadyFetchedPresentInBookmarks = false; + _messages = new SD.HnD.DAL.CollectionClasses.MessageCollection(new MessageEntityFactory()); + _messages.SetContainingEntityInfo(this, "Thread"); + _alwaysFetchMessages = false; + _alreadyFetchedMessages = false; + _threadSubscription = new SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection(new ThreadSubscriptionEntityFactory()); + _threadSubscription.SetContainingEntityInfo(this, "Thread"); + _alwaysFetchThreadSubscription = false; + _alreadyFetchedThreadSubscription = false; + _usersWhoSubscribedThread = new SD.HnD.DAL.CollectionClasses.UserCollection(new UserEntityFactory()); + _alwaysFetchUsersWhoSubscribedThread = false; + _alreadyFetchedUsersWhoSubscribedThread = false; + _usersWhoPostedInThread = new SD.HnD.DAL.CollectionClasses.UserCollection(new UserEntityFactory()); + _alwaysFetchUsersWhoPostedInThread = false; + _alreadyFetchedUsersWhoPostedInThread = false; + _usersWhoBookmarkedThread = new SD.HnD.DAL.CollectionClasses.UserCollection(new UserEntityFactory()); + _alwaysFetchUsersWhoBookmarkedThread = false; + _alreadyFetchedUsersWhoBookmarkedThread = false; + _forum = null; + _forumReturnsNewIfNotFound = true; + _alwaysFetchForum = false; + _alreadyFetchedForum = false; + _userWhoStartedThread = null; + _userWhoStartedThreadReturnsNewIfNotFound = true; + _alwaysFetchUserWhoStartedThread = false; + _alreadyFetchedUserWhoStartedThread = false; + _supportQueueThread = null; + _supportQueueThreadReturnsNewIfNotFound = true; + _alwaysFetchSupportQueueThread = false; + _alreadyFetchedSupportQueueThread = false; + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ForumID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Subject", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("StartedByUserID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ThreadLastPostingDate", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IsSticky", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IsClosed", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("MarkedAsDone", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("NumberOfViews", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Memo", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _forum + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncForum(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _forum, new PropertyChangedEventHandler( OnForumPropertyChanged ), "Forum", ThreadEntity.Relations.ForumEntityUsingForumID, true, signalRelatedEntity, "Threads", resetFKFields, new int[] { (int)ThreadFieldIndex.ForumID } ); + _forum = null; + } + + /// setups the sync logic for member _forum + /// Instance to set as the related entity of type entityType + private void SetupSyncForum(IEntity relatedEntity) + { + if(_forum!=relatedEntity) + { + DesetupSyncForum(true, true); + _forum = (ForumEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _forum, new PropertyChangedEventHandler( OnForumPropertyChanged ), "Forum", ThreadEntity.Relations.ForumEntityUsingForumID, true, ref _alreadyFetchedForum, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnForumPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _userWhoStartedThread + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncUserWhoStartedThread(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _userWhoStartedThread, new PropertyChangedEventHandler( OnUserWhoStartedThreadPropertyChanged ), "UserWhoStartedThread", ThreadEntity.Relations.UserEntityUsingStartedByUserID, true, signalRelatedEntity, "StartedThreads", resetFKFields, new int[] { (int)ThreadFieldIndex.StartedByUserID } ); + _userWhoStartedThread = null; + } + + /// setups the sync logic for member _userWhoStartedThread + /// Instance to set as the related entity of type entityType + private void SetupSyncUserWhoStartedThread(IEntity relatedEntity) + { + if(_userWhoStartedThread!=relatedEntity) + { + DesetupSyncUserWhoStartedThread(true, true); + _userWhoStartedThread = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _userWhoStartedThread, new PropertyChangedEventHandler( OnUserWhoStartedThreadPropertyChanged ), "UserWhoStartedThread", ThreadEntity.Relations.UserEntityUsingStartedByUserID, true, ref _alreadyFetchedUserWhoStartedThread, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnUserWhoStartedThreadPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _supportQueueThread + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncSupportQueueThread(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _supportQueueThread, new PropertyChangedEventHandler( OnSupportQueueThreadPropertyChanged ), "SupportQueueThread", ThreadEntity.Relations.SupportQueueThreadEntityUsingThreadID, false, signalRelatedEntity, "Thread", false, new int[] { (int)ThreadFieldIndex.ThreadID } ); + _supportQueueThread = null; + } + + /// setups the sync logic for member _supportQueueThread + /// Instance to set as the related entity of type entityType + private void SetupSyncSupportQueueThread(IEntity relatedEntity) + { + if(_supportQueueThread!=relatedEntity) + { + DesetupSyncSupportQueueThread(true, true); + _supportQueueThread = (SupportQueueThreadEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _supportQueueThread, new PropertyChangedEventHandler( OnSupportQueueThreadPropertyChanged ), "SupportQueueThread", ThreadEntity.Relations.SupportQueueThreadEntityUsingThreadID, false, ref _alreadyFetchedSupportQueueThread, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnSupportQueueThreadPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for Thread which data should be fetched into this Thread object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)ThreadFieldIndex.ThreadID].ForcedCurrentValueWrite(threadID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateThreadDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new ThreadEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static ThreadRelations Relations + { + get { return new ThreadRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'AuditDataThreadRelated' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathAuditDataThreadRelated + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection(), + (IEntityRelation)GetRelationsForField("AuditDataThreadRelated")[0], (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity, 0, null, null, null, "AuditDataThreadRelated", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Bookmark' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathPresentInBookmarks + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.BookmarkCollection(), + (IEntityRelation)GetRelationsForField("PresentInBookmarks")[0], (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.BookmarkEntity, 0, null, null, null, "PresentInBookmarks", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Message' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathMessages + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.MessageCollection(), + (IEntityRelation)GetRelationsForField("Messages")[0], (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.MessageEntity, 0, null, null, null, "Messages", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'ThreadSubscription' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThreadSubscription + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection(), + (IEntityRelation)GetRelationsForField("ThreadSubscription")[0], (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.ThreadSubscriptionEntity, 0, null, null, null, "ThreadSubscription", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUsersWhoSubscribedThread + { + get + { + IEntityRelation intermediateRelation = ThreadEntity.Relations.ThreadSubscriptionEntityUsingThreadID; + intermediateRelation.SetAliases(string.Empty, "ThreadSubscription_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, GetRelationsForField("UsersWhoSubscribedThread"), "UsersWhoSubscribedThread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUsersWhoPostedInThread + { + get + { + IEntityRelation intermediateRelation = ThreadEntity.Relations.MessageEntityUsingThreadID; + intermediateRelation.SetAliases(string.Empty, "Message_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, GetRelationsForField("UsersWhoPostedInThread"), "UsersWhoPostedInThread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUsersWhoBookmarkedThread + { + get + { + IEntityRelation intermediateRelation = ThreadEntity.Relations.BookmarkEntityUsingThreadID; + intermediateRelation.SetAliases(string.Empty, "Bookmark_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, GetRelationsForField("UsersWhoBookmarkedThread"), "UsersWhoBookmarkedThread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Forum' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathForum + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ForumCollection(), + (IEntityRelation)GetRelationsForField("Forum")[0], (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.ForumEntity, 0, null, null, null, "Forum", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUserWhoStartedThread + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("UserWhoStartedThread")[0], (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "UserWhoStartedThread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'SupportQueueThread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSupportQueueThread + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection(), + (IEntityRelation)GetRelationsForField("SupportQueueThread")[0], (int)SD.HnD.DAL.EntityType.ThreadEntity, (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity, 0, null, null, null, "SupportQueueThread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToOne); + } + } + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "ThreadEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return ThreadEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return ThreadEntity.FieldsCustomProperties;} + } + + /// The ThreadID property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."ThreadID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 ThreadID + { + get { return (System.Int32)GetValue((int)ThreadFieldIndex.ThreadID, true); } + set { SetValue((int)ThreadFieldIndex.ThreadID, value, true); } + } + /// The ForumID property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."ForumID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 ForumID + { + get { return (System.Int32)GetValue((int)ThreadFieldIndex.ForumID, true); } + set { SetValue((int)ThreadFieldIndex.ForumID, value, true); } + } + /// The Subject property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."Subject"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 250
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String Subject + { + get { return (System.String)GetValue((int)ThreadFieldIndex.Subject, true); } + set { SetValue((int)ThreadFieldIndex.Subject, value, true); } + } + /// The StartedByUserID property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."StartedByUserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 StartedByUserID + { + get { return (System.Int32)GetValue((int)ThreadFieldIndex.StartedByUserID, true); } + set { SetValue((int)ThreadFieldIndex.StartedByUserID, value, true); } + } + /// The ThreadLastPostingDate property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."ThreadLastPostingDate"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable ThreadLastPostingDate + { + get { return (Nullable)GetValue((int)ThreadFieldIndex.ThreadLastPostingDate, false); } + set { SetValue((int)ThreadFieldIndex.ThreadLastPostingDate, value, true); } + } + /// The IsSticky property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."IsSticky"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean IsSticky + { + get { return (System.Boolean)GetValue((int)ThreadFieldIndex.IsSticky, true); } + set { SetValue((int)ThreadFieldIndex.IsSticky, value, true); } + } + /// The IsClosed property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."IsClosed"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean IsClosed + { + get { return (System.Boolean)GetValue((int)ThreadFieldIndex.IsClosed, true); } + set { SetValue((int)ThreadFieldIndex.IsClosed, value, true); } + } + /// The MarkedAsDone property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."MarkedAsDone"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean MarkedAsDone + { + get { return (System.Boolean)GetValue((int)ThreadFieldIndex.MarkedAsDone, true); } + set { SetValue((int)ThreadFieldIndex.MarkedAsDone, value, true); } + } + /// The NumberOfViews property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."NumberOfViews"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable NumberOfViews + { + get { return (Nullable)GetValue((int)ThreadFieldIndex.NumberOfViews, false); } + set { SetValue((int)ThreadFieldIndex.NumberOfViews, value, true); } + } + /// The Memo property of the Entity Thread

+ ///
+ /// Mapped on table field: "Thread"."Memo"
+ /// Table field type characteristics (type, precision, scale, length): NText, 0, 0, 1073741823
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String Memo + { + get { return (System.String)GetValue((int)ThreadFieldIndex.Memo, true); } + set { SetValue((int)ThreadFieldIndex.Memo, value, true); } + } + + /// Retrieves all related entities of type 'AuditDataThreadRelatedEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiAuditDataThreadRelated()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.AuditDataThreadRelatedCollection AuditDataThreadRelated + { + get { return GetMultiAuditDataThreadRelated(false); } + } + + /// Gets / sets the lazy loading flag for AuditDataThreadRelated. When set to true, AuditDataThreadRelated is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time AuditDataThreadRelated is accessed. You can always execute + /// a forced fetch by calling GetMultiAuditDataThreadRelated(true). + [Browsable(false)] + public bool AlwaysFetchAuditDataThreadRelated + { + get { return _alwaysFetchAuditDataThreadRelated; } + set { _alwaysFetchAuditDataThreadRelated = value; } + } + + /// Gets / Sets the lazy loading flag if the property AuditDataThreadRelated already has been fetched. Setting this property to false when AuditDataThreadRelated has been fetched + /// will clear the AuditDataThreadRelated collection well. Setting this property to true while AuditDataThreadRelated hasn't been fetched disables lazy loading for AuditDataThreadRelated + [Browsable(false)] + public bool AlreadyFetchedAuditDataThreadRelated + { + get { return _alreadyFetchedAuditDataThreadRelated;} + set + { + if(_alreadyFetchedAuditDataThreadRelated && !value && (_auditDataThreadRelated != null)) + { + _auditDataThreadRelated.Clear(); + } + _alreadyFetchedAuditDataThreadRelated = value; + } + } + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiPresentInBookmarks()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.BookmarkCollection PresentInBookmarks + { + get { return GetMultiPresentInBookmarks(false); } + } + + /// Gets / sets the lazy loading flag for PresentInBookmarks. When set to true, PresentInBookmarks is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time PresentInBookmarks is accessed. You can always execute + /// a forced fetch by calling GetMultiPresentInBookmarks(true). + [Browsable(false)] + public bool AlwaysFetchPresentInBookmarks + { + get { return _alwaysFetchPresentInBookmarks; } + set { _alwaysFetchPresentInBookmarks = value; } + } + + /// Gets / Sets the lazy loading flag if the property PresentInBookmarks already has been fetched. Setting this property to false when PresentInBookmarks has been fetched + /// will clear the PresentInBookmarks collection well. Setting this property to true while PresentInBookmarks hasn't been fetched disables lazy loading for PresentInBookmarks + [Browsable(false)] + public bool AlreadyFetchedPresentInBookmarks + { + get { return _alreadyFetchedPresentInBookmarks;} + set + { + if(_alreadyFetchedPresentInBookmarks && !value && (_presentInBookmarks != null)) + { + _presentInBookmarks.Clear(); + } + _alreadyFetchedPresentInBookmarks = value; + } + } + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiMessages()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.MessageCollection Messages + { + get { return GetMultiMessages(false); } + } + + /// Gets / sets the lazy loading flag for Messages. When set to true, Messages is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Messages is accessed. You can always execute + /// a forced fetch by calling GetMultiMessages(true). + [Browsable(false)] + public bool AlwaysFetchMessages + { + get { return _alwaysFetchMessages; } + set { _alwaysFetchMessages = value; } + } + + /// Gets / Sets the lazy loading flag if the property Messages already has been fetched. Setting this property to false when Messages has been fetched + /// will clear the Messages collection well. Setting this property to true while Messages hasn't been fetched disables lazy loading for Messages + [Browsable(false)] + public bool AlreadyFetchedMessages + { + get { return _alreadyFetchedMessages;} + set + { + if(_alreadyFetchedMessages && !value && (_messages != null)) + { + _messages.Clear(); + } + _alreadyFetchedMessages = value; + } + } + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiThreadSubscription()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection ThreadSubscription + { + get { return GetMultiThreadSubscription(false); } + } + + /// Gets / sets the lazy loading flag for ThreadSubscription. When set to true, ThreadSubscription is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ThreadSubscription is accessed. You can always execute + /// a forced fetch by calling GetMultiThreadSubscription(true). + [Browsable(false)] + public bool AlwaysFetchThreadSubscription + { + get { return _alwaysFetchThreadSubscription; } + set { _alwaysFetchThreadSubscription = value; } + } + + /// Gets / Sets the lazy loading flag if the property ThreadSubscription already has been fetched. Setting this property to false when ThreadSubscription has been fetched + /// will clear the ThreadSubscription collection well. Setting this property to true while ThreadSubscription hasn't been fetched disables lazy loading for ThreadSubscription + [Browsable(false)] + public bool AlreadyFetchedThreadSubscription + { + get { return _alreadyFetchedThreadSubscription;} + set + { + if(_alreadyFetchedThreadSubscription && !value && (_threadSubscription != null)) + { + _threadSubscription.Clear(); + } + _alreadyFetchedThreadSubscription = value; + } + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiUsersWhoSubscribedThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.UserCollection UsersWhoSubscribedThread + { + get { return GetMultiUsersWhoSubscribedThread(false); } + } + + /// Gets / sets the lazy loading flag for UsersWhoSubscribedThread. When set to true, UsersWhoSubscribedThread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time UsersWhoSubscribedThread is accessed. You can always execute + /// a forced fetch by calling GetMultiUsersWhoSubscribedThread(true). + [Browsable(false)] + public bool AlwaysFetchUsersWhoSubscribedThread + { + get { return _alwaysFetchUsersWhoSubscribedThread; } + set { _alwaysFetchUsersWhoSubscribedThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property UsersWhoSubscribedThread already has been fetched. Setting this property to false when UsersWhoSubscribedThread has been fetched + /// will clear the UsersWhoSubscribedThread collection well. Setting this property to true while UsersWhoSubscribedThread hasn't been fetched disables lazy loading for UsersWhoSubscribedThread + [Browsable(false)] + public bool AlreadyFetchedUsersWhoSubscribedThread + { + get { return _alreadyFetchedUsersWhoSubscribedThread;} + set + { + if(_alreadyFetchedUsersWhoSubscribedThread && !value && (_usersWhoSubscribedThread != null)) + { + _usersWhoSubscribedThread.Clear(); + } + _alreadyFetchedUsersWhoSubscribedThread = value; + } + } + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiUsersWhoPostedInThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.UserCollection UsersWhoPostedInThread + { + get { return GetMultiUsersWhoPostedInThread(false); } + } + + /// Gets / sets the lazy loading flag for UsersWhoPostedInThread. When set to true, UsersWhoPostedInThread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time UsersWhoPostedInThread is accessed. You can always execute + /// a forced fetch by calling GetMultiUsersWhoPostedInThread(true). + [Browsable(false)] + public bool AlwaysFetchUsersWhoPostedInThread + { + get { return _alwaysFetchUsersWhoPostedInThread; } + set { _alwaysFetchUsersWhoPostedInThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property UsersWhoPostedInThread already has been fetched. Setting this property to false when UsersWhoPostedInThread has been fetched + /// will clear the UsersWhoPostedInThread collection well. Setting this property to true while UsersWhoPostedInThread hasn't been fetched disables lazy loading for UsersWhoPostedInThread + [Browsable(false)] + public bool AlreadyFetchedUsersWhoPostedInThread + { + get { return _alreadyFetchedUsersWhoPostedInThread;} + set + { + if(_alreadyFetchedUsersWhoPostedInThread && !value && (_usersWhoPostedInThread != null)) + { + _usersWhoPostedInThread.Clear(); + } + _alreadyFetchedUsersWhoPostedInThread = value; + } + } + /// Retrieves all related entities of type 'UserEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiUsersWhoBookmarkedThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.UserCollection UsersWhoBookmarkedThread + { + get { return GetMultiUsersWhoBookmarkedThread(false); } + } + + /// Gets / sets the lazy loading flag for UsersWhoBookmarkedThread. When set to true, UsersWhoBookmarkedThread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time UsersWhoBookmarkedThread is accessed. You can always execute + /// a forced fetch by calling GetMultiUsersWhoBookmarkedThread(true). + [Browsable(false)] + public bool AlwaysFetchUsersWhoBookmarkedThread + { + get { return _alwaysFetchUsersWhoBookmarkedThread; } + set { _alwaysFetchUsersWhoBookmarkedThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property UsersWhoBookmarkedThread already has been fetched. Setting this property to false when UsersWhoBookmarkedThread has been fetched + /// will clear the UsersWhoBookmarkedThread collection well. Setting this property to true while UsersWhoBookmarkedThread hasn't been fetched disables lazy loading for UsersWhoBookmarkedThread + [Browsable(false)] + public bool AlreadyFetchedUsersWhoBookmarkedThread + { + get { return _alreadyFetchedUsersWhoBookmarkedThread;} + set + { + if(_alreadyFetchedUsersWhoBookmarkedThread && !value && (_usersWhoBookmarkedThread != null)) + { + _usersWhoBookmarkedThread.Clear(); + } + _alreadyFetchedUsersWhoBookmarkedThread = value; + } + } + + /// Gets / sets related entity of type 'ForumEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleForum()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ForumEntity Forum + { + get { return GetSingleForum(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncForum(value); + } + else + { + if(value==null) + { + if(_forum != null) + { + _forum.UnsetRelatedEntity(this, "Threads"); + } + } + else + { + if(_forum!=value) + { + ((IEntity)value).SetRelatedEntity(this, "Threads"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Forum. When set to true, Forum is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Forum is accessed. You can always execute + /// a forced fetch by calling GetSingleForum(true). + [Browsable(false)] + public bool AlwaysFetchForum + { + get { return _alwaysFetchForum; } + set { _alwaysFetchForum = value; } + } + + /// Gets / Sets the lazy loading flag if the property Forum already has been fetched. Setting this property to false when Forum has been fetched + /// will set Forum to null as well. Setting this property to true while Forum hasn't been fetched disables lazy loading for Forum + [Browsable(false)] + public bool AlreadyFetchedForum + { + get { return _alreadyFetchedForum;} + set + { + if(_alreadyFetchedForum && !value) + { + this.Forum = null; + } + _alreadyFetchedForum = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Forum is not found + /// in the database. When set to true, Forum will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ForumReturnsNewIfNotFound + { + get { return _forumReturnsNewIfNotFound; } + set { _forumReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleUserWhoStartedThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity UserWhoStartedThread + { + get { return GetSingleUserWhoStartedThread(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncUserWhoStartedThread(value); + } + else + { + if(value==null) + { + if(_userWhoStartedThread != null) + { + _userWhoStartedThread.UnsetRelatedEntity(this, "StartedThreads"); + } + } + else + { + if(_userWhoStartedThread!=value) + { + ((IEntity)value).SetRelatedEntity(this, "StartedThreads"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for UserWhoStartedThread. When set to true, UserWhoStartedThread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time UserWhoStartedThread is accessed. You can always execute + /// a forced fetch by calling GetSingleUserWhoStartedThread(true). + [Browsable(false)] + public bool AlwaysFetchUserWhoStartedThread + { + get { return _alwaysFetchUserWhoStartedThread; } + set { _alwaysFetchUserWhoStartedThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property UserWhoStartedThread already has been fetched. Setting this property to false when UserWhoStartedThread has been fetched + /// will set UserWhoStartedThread to null as well. Setting this property to true while UserWhoStartedThread hasn't been fetched disables lazy loading for UserWhoStartedThread + [Browsable(false)] + public bool AlreadyFetchedUserWhoStartedThread + { + get { return _alreadyFetchedUserWhoStartedThread;} + set + { + if(_alreadyFetchedUserWhoStartedThread && !value) + { + this.UserWhoStartedThread = null; + } + _alreadyFetchedUserWhoStartedThread = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property UserWhoStartedThread is not found + /// in the database. When set to true, UserWhoStartedThread will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool UserWhoStartedThreadReturnsNewIfNotFound + { + get { return _userWhoStartedThreadReturnsNewIfNotFound; } + set { _userWhoStartedThreadReturnsNewIfNotFound = value; } + } + + /// Gets / sets related entity of type 'SupportQueueThreadEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleSupportQueueThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual SupportQueueThreadEntity SupportQueueThread + { + get { return GetSingleSupportQueueThread(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncSupportQueueThread(value); + } + else + { + if(value==null) + { + DesetupSyncSupportQueueThread(true, true); + } + else + { + if(_supportQueueThread!=value) + { + IEntity relatedEntity = (IEntity)value; + relatedEntity.SetRelatedEntity(this, "Thread"); + SetupSyncSupportQueueThread(relatedEntity); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for SupportQueueThread. When set to true, SupportQueueThread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SupportQueueThread is accessed. You can always execute + /// a forced fetch by calling GetSingleSupportQueueThread(true). + [Browsable(false)] + public bool AlwaysFetchSupportQueueThread + { + get { return _alwaysFetchSupportQueueThread; } + set { _alwaysFetchSupportQueueThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property SupportQueueThread already has been fetched. Setting this property to false when SupportQueueThread has been fetched + /// will set SupportQueueThread to null as well. Setting this property to true while SupportQueueThread hasn't been fetched disables lazy loading for SupportQueueThread + [Browsable(false)] + public bool AlreadyFetchedSupportQueueThread + { + get { return _alreadyFetchedSupportQueueThread;} + set + { + if(_alreadyFetchedSupportQueueThread && !value) + { + this.SupportQueueThread = null; + } + _alreadyFetchedSupportQueueThread = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property SupportQueueThread is not found + /// in the database. When set to true, SupportQueueThread will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool SupportQueueThreadReturnsNewIfNotFound + { + get { return _supportQueueThreadReturnsNewIfNotFound; } + set { _supportQueueThreadReturnsNewIfNotFound = value; } + } + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.ThreadEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/ThreadSubscriptionEntityBase.cs b/DAL/EntityBaseClasses/ThreadSubscriptionEntityBase.cs new file mode 100644 index 0000000..b6b27e8 --- /dev/null +++ b/DAL/EntityBaseClasses/ThreadSubscriptionEntityBase.cs @@ -0,0 +1,1089 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'ThreadSubscription'.

+ /// + ///
+ [Serializable] + public abstract partial class ThreadSubscriptionEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + + private ThreadEntity _thread; + private bool _alwaysFetchThread, _alreadyFetchedThread, _threadReturnsNewIfNotFound; + private UserEntity _user; + private bool _alwaysFetchUser, _alreadyFetchedUser, _userReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name Thread + public static readonly string Thread = "Thread"; + /// Member name User + public static readonly string User = "User"; + + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static ThreadSubscriptionEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public ThreadSubscriptionEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + public ThreadSubscriptionEntityBase(System.Int32 userID, System.Int32 threadID) + { + InitClassFetch(userID, threadID, null, null); + } + + /// CTor + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ThreadSubscriptionEntityBase(System.Int32 userID, System.Int32 threadID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(userID, threadID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// The custom validator object for this ThreadSubscriptionEntity + public ThreadSubscriptionEntityBase(System.Int32 userID, System.Int32 threadID, IValidator validator) + { + InitClassFetch(userID, threadID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected ThreadSubscriptionEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + + _thread = (ThreadEntity)info.GetValue("_thread", typeof(ThreadEntity)); + if(_thread!=null) + { + _thread.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _threadReturnsNewIfNotFound = info.GetBoolean("_threadReturnsNewIfNotFound"); + _alwaysFetchThread = info.GetBoolean("_alwaysFetchThread"); + _alreadyFetchedThread = info.GetBoolean("_alreadyFetchedThread"); + _user = (UserEntity)info.GetValue("_user", typeof(UserEntity)); + if(_user!=null) + { + _user.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _userReturnsNewIfNotFound = info.GetBoolean("_userReturnsNewIfNotFound"); + _alwaysFetchUser = info.GetBoolean("_alwaysFetchUser"); + _alreadyFetchedUser = info.GetBoolean("_alreadyFetchedUser"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((ThreadSubscriptionFieldIndex)fieldIndex) + { + case ThreadSubscriptionFieldIndex.UserID: + DesetupSyncUser(true, false); + _alreadyFetchedUser = false; + break; + case ThreadSubscriptionFieldIndex.ThreadID: + DesetupSyncThread(true, false); + _alreadyFetchedThread = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + + + _alreadyFetchedThread = (_thread != null); + _alreadyFetchedUser = (_user != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return ThreadSubscriptionEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "Thread": + toReturn.Add(ThreadSubscriptionEntity.Relations.ThreadEntityUsingThreadID); + break; + case "User": + toReturn.Add(ThreadSubscriptionEntity.Relations.UserEntityUsingUserID); + break; + + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + + + info.AddValue("_thread", (!this.MarkedForDeletion?_thread:null)); + info.AddValue("_threadReturnsNewIfNotFound", _threadReturnsNewIfNotFound); + info.AddValue("_alwaysFetchThread", _alwaysFetchThread); + info.AddValue("_alreadyFetchedThread", _alreadyFetchedThread); + info.AddValue("_user", (!this.MarkedForDeletion?_user:null)); + info.AddValue("_userReturnsNewIfNotFound", _userReturnsNewIfNotFound); + info.AddValue("_alwaysFetchUser", _alwaysFetchUser); + info.AddValue("_alreadyFetchedUser", _alreadyFetchedUser); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "Thread": + _alreadyFetchedThread = true; + this.Thread = (ThreadEntity)entity; + break; + case "User": + _alreadyFetchedUser = true; + this.User = (UserEntity)entity; + break; + + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "Thread": + SetupSyncThread(relatedEntity); + break; + case "User": + SetupSyncUser(relatedEntity); + break; + + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "Thread": + DesetupSyncThread(false, true); + break; + case "User": + DesetupSyncUser(false, true); + break; + + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_thread!=null) + { + toReturn.Add(_thread); + } + if(_user!=null) + { + toReturn.Add(_user); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userID, System.Int32 threadID) + { + return FetchUsingPK(userID, threadID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userID, System.Int32 threadID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(userID, threadID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userID, System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(userID, threadID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userID, System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(userID, threadID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.UserID, this.ThreadID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(ThreadSubscriptionFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(ThreadSubscriptionFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new ThreadSubscriptionRelations().GetAllRelations(); + } + + + + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type 'n:1' + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public ThreadEntity GetSingleThread() + { + return GetSingleThread(false); + } + + /// Retrieves the related entity of type 'ThreadEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'ThreadEntity' which is related to this entity. + public virtual ThreadEntity GetSingleThread(bool forceFetch) + { + if( ( !_alreadyFetchedThread || forceFetch || _alwaysFetchThread) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ThreadSubscriptionEntity.Relations.ThreadEntityUsingThreadID); + + ThreadEntity newEntity = new ThreadEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.ThreadID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (ThreadEntity)base.ActiveContext.Get(newEntity); + } + this.Thread = newEntity; + } + else + { + if(_threadReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_thread == null))) + { + this.Thread = newEntity; + } + } + else + { + this.Thread = null; + } + } + _alreadyFetchedThread = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _thread; + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserEntity' which is related to this entity. + public UserEntity GetSingleUser() + { + return GetSingleUser(false); + } + + /// Retrieves the related entity of type 'UserEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserEntity' which is related to this entity. + public virtual UserEntity GetSingleUser(bool forceFetch) + { + if( ( !_alreadyFetchedUser || forceFetch || _alwaysFetchUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(ThreadSubscriptionEntity.Relations.UserEntityUsingUserID); + + UserEntity newEntity = new UserEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.UserID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserEntity)base.ActiveContext.Get(newEntity); + } + this.User = newEntity; + } + else + { + if(_userReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_user == null))) + { + this.User = newEntity; + } + } + else + { + this.User = null; + } + } + _alreadyFetchedUser = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _user; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + ThreadSubscriptionDAO dao = (ThreadSubscriptionDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + + + if(_thread!=null) + { + _thread.ActiveContext = base.ActiveContext; + } + if(_user!=null) + { + _user.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + ThreadSubscriptionDAO dao = (ThreadSubscriptionDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + ThreadSubscriptionDAO dao = (ThreadSubscriptionDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.ThreadSubscriptionEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("Thread", _thread); + toReturn.Add("User", _user); + + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// The validator object for this ThreadSubscriptionEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 userID, System.Int32 threadID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(userID, threadID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + + + _thread = null; + _threadReturnsNewIfNotFound = true; + _alwaysFetchThread = false; + _alreadyFetchedThread = false; + _user = null; + _userReturnsNewIfNotFound = true; + _alwaysFetchUser = false; + _alreadyFetchedUser = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("UserID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _thread + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncThread(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", ThreadSubscriptionEntity.Relations.ThreadEntityUsingThreadID, true, signalRelatedEntity, "ThreadSubscription", resetFKFields, new int[] { (int)ThreadSubscriptionFieldIndex.ThreadID } ); + _thread = null; + } + + /// setups the sync logic for member _thread + /// Instance to set as the related entity of type entityType + private void SetupSyncThread(IEntity relatedEntity) + { + if(_thread!=relatedEntity) + { + DesetupSyncThread(true, true); + _thread = (ThreadEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _thread, new PropertyChangedEventHandler( OnThreadPropertyChanged ), "Thread", ThreadSubscriptionEntity.Relations.ThreadEntityUsingThreadID, true, ref _alreadyFetchedThread, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnThreadPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + /// Removes the sync logic for member _user + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncUser(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _user, new PropertyChangedEventHandler( OnUserPropertyChanged ), "User", ThreadSubscriptionEntity.Relations.UserEntityUsingUserID, true, signalRelatedEntity, "ThreadSubscription", resetFKFields, new int[] { (int)ThreadSubscriptionFieldIndex.UserID } ); + _user = null; + } + + /// setups the sync logic for member _user + /// Instance to set as the related entity of type entityType + private void SetupSyncUser(IEntity relatedEntity) + { + if(_user!=relatedEntity) + { + DesetupSyncUser(true, true); + _user = (UserEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _user, new PropertyChangedEventHandler( OnUserPropertyChanged ), "User", ThreadSubscriptionEntity.Relations.UserEntityUsingUserID, true, ref _alreadyFetchedUser, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnUserPropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 userID, System.Int32 threadID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)ThreadSubscriptionFieldIndex.UserID].ForcedCurrentValueWrite(userID); + base.Fields[(int)ThreadSubscriptionFieldIndex.ThreadID].ForcedCurrentValueWrite(threadID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateThreadSubscriptionDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new ThreadSubscriptionEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static ThreadSubscriptionRelations Relations + { + get { return new ThreadSubscriptionRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThread + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), + (IEntityRelation)GetRelationsForField("Thread")[0], (int)SD.HnD.DAL.EntityType.ThreadSubscriptionEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, null, "Thread", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("User")[0], (int)SD.HnD.DAL.EntityType.ThreadSubscriptionEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "User", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "ThreadSubscriptionEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return ThreadSubscriptionEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return ThreadSubscriptionEntity.FieldsCustomProperties;} + } + + /// The UserID property of the Entity ThreadSubscription

+ ///
+ /// Mapped on table field: "ThreadSubscription"."UserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 UserID + { + get { return (System.Int32)GetValue((int)ThreadSubscriptionFieldIndex.UserID, true); } + set { SetValue((int)ThreadSubscriptionFieldIndex.UserID, value, true); } + } + /// The ThreadID property of the Entity ThreadSubscription

+ ///
+ /// Mapped on table field: "ThreadSubscription"."ThreadID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, false
+ public virtual System.Int32 ThreadID + { + get { return (System.Int32)GetValue((int)ThreadSubscriptionFieldIndex.ThreadID, true); } + set { SetValue((int)ThreadSubscriptionFieldIndex.ThreadID, value, true); } + } + + + + /// Gets / sets related entity of type 'ThreadEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleThread()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual ThreadEntity Thread + { + get { return GetSingleThread(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncThread(value); + } + else + { + if(value==null) + { + if(_thread != null) + { + _thread.UnsetRelatedEntity(this, "ThreadSubscription"); + } + } + else + { + if(_thread!=value) + { + ((IEntity)value).SetRelatedEntity(this, "ThreadSubscription"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for Thread. When set to true, Thread is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Thread is accessed. You can always execute + /// a forced fetch by calling GetSingleThread(true). + [Browsable(false)] + public bool AlwaysFetchThread + { + get { return _alwaysFetchThread; } + set { _alwaysFetchThread = value; } + } + + /// Gets / Sets the lazy loading flag if the property Thread already has been fetched. Setting this property to false when Thread has been fetched + /// will set Thread to null as well. Setting this property to true while Thread hasn't been fetched disables lazy loading for Thread + [Browsable(false)] + public bool AlreadyFetchedThread + { + get { return _alreadyFetchedThread;} + set + { + if(_alreadyFetchedThread && !value) + { + this.Thread = null; + } + _alreadyFetchedThread = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property Thread is not found + /// in the database. When set to true, Thread will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool ThreadReturnsNewIfNotFound + { + get { return _threadReturnsNewIfNotFound; } + set { _threadReturnsNewIfNotFound = value; } + } + /// Gets / sets related entity of type 'UserEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserEntity User + { + get { return GetSingleUser(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncUser(value); + } + else + { + if(value==null) + { + if(_user != null) + { + _user.UnsetRelatedEntity(this, "ThreadSubscription"); + } + } + else + { + if(_user!=value) + { + ((IEntity)value).SetRelatedEntity(this, "ThreadSubscription"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for User. When set to true, User is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time User is accessed. You can always execute + /// a forced fetch by calling GetSingleUser(true). + [Browsable(false)] + public bool AlwaysFetchUser + { + get { return _alwaysFetchUser; } + set { _alwaysFetchUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property User already has been fetched. Setting this property to false when User has been fetched + /// will set User to null as well. Setting this property to true while User hasn't been fetched disables lazy loading for User + [Browsable(false)] + public bool AlreadyFetchedUser + { + get { return _alreadyFetchedUser;} + set + { + if(_alreadyFetchedUser && !value) + { + this.User = null; + } + _alreadyFetchedUser = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property User is not found + /// in the database. When set to true, User will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool UserReturnsNewIfNotFound + { + get { return _userReturnsNewIfNotFound; } + set { _userReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.ThreadSubscriptionEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/UserEntityBase.cs b/DAL/EntityBaseClasses/UserEntityBase.cs new file mode 100644 index 0000000..f34b01b --- /dev/null +++ b/DAL/EntityBaseClasses/UserEntityBase.cs @@ -0,0 +1,3012 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'User'.

+ /// + ///
+ [Serializable] + public abstract partial class UserEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection _loggedAudits; + private bool _alwaysFetchLoggedAudits, _alreadyFetchedLoggedAudits; + private SD.HnD.DAL.CollectionClasses.BookmarkCollection _bookmarks; + private bool _alwaysFetchBookmarks, _alreadyFetchedBookmarks; + private SD.HnD.DAL.CollectionClasses.IPBanCollection _iPBansSet; + private bool _alwaysFetchIPBansSet, _alreadyFetchedIPBansSet; + private SD.HnD.DAL.CollectionClasses.MessageCollection _postedMessages; + private bool _alwaysFetchPostedMessages, _alreadyFetchedPostedMessages; + private SD.HnD.DAL.CollectionClasses.RoleUserCollection _roleUser; + private bool _alwaysFetchRoleUser, _alreadyFetchedRoleUser; + private SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection _supportQueueThreadsClaimed; + private bool _alwaysFetchSupportQueueThreadsClaimed, _alreadyFetchedSupportQueueThreadsClaimed; + private SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection _supportQueueThreadsPlaced; + private bool _alwaysFetchSupportQueueThreadsPlaced, _alreadyFetchedSupportQueueThreadsPlaced; + private SD.HnD.DAL.CollectionClasses.ThreadCollection _startedThreads; + private bool _alwaysFetchStartedThreads, _alreadyFetchedStartedThreads; + private SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection _threadSubscription; + private bool _alwaysFetchThreadSubscription, _alreadyFetchedThreadSubscription; + private SD.HnD.DAL.CollectionClasses.ForumCollection _startedThreadsInForums; + private bool _alwaysFetchStartedThreadsInForums, _alreadyFetchedStartedThreadsInForums; + private SD.HnD.DAL.CollectionClasses.RoleCollection _roles; + private bool _alwaysFetchRoles, _alreadyFetchedRoles; + private SD.HnD.DAL.CollectionClasses.ThreadCollection _threadCollectionViaThreadSubscription; + private bool _alwaysFetchThreadCollectionViaThreadSubscription, _alreadyFetchedThreadCollectionViaThreadSubscription; + private SD.HnD.DAL.CollectionClasses.ThreadCollection _postedMessagesInThreads; + private bool _alwaysFetchPostedMessagesInThreads, _alreadyFetchedPostedMessagesInThreads; + private SD.HnD.DAL.CollectionClasses.ThreadCollection _threadsInBookmarks; + private bool _alwaysFetchThreadsInBookmarks, _alreadyFetchedThreadsInBookmarks; + private UserTitleEntity _userTitle; + private bool _alwaysFetchUserTitle, _alreadyFetchedUserTitle, _userTitleReturnsNewIfNotFound; + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + /// Member name UserTitle + public static readonly string UserTitle = "UserTitle"; + /// Member name LoggedAudits + public static readonly string LoggedAudits = "LoggedAudits"; + /// Member name Bookmarks + public static readonly string Bookmarks = "Bookmarks"; + /// Member name IPBansSet + public static readonly string IPBansSet = "IPBansSet"; + /// Member name PostedMessages + public static readonly string PostedMessages = "PostedMessages"; + /// Member name RoleUser + public static readonly string RoleUser = "RoleUser"; + /// Member name SupportQueueThreadsClaimed + public static readonly string SupportQueueThreadsClaimed = "SupportQueueThreadsClaimed"; + /// Member name SupportQueueThreadsPlaced + public static readonly string SupportQueueThreadsPlaced = "SupportQueueThreadsPlaced"; + /// Member name StartedThreads + public static readonly string StartedThreads = "StartedThreads"; + /// Member name ThreadSubscription + public static readonly string ThreadSubscription = "ThreadSubscription"; + /// Member name StartedThreadsInForums + public static readonly string StartedThreadsInForums = "StartedThreadsInForums"; + /// Member name Roles + public static readonly string Roles = "Roles"; + /// Member name ThreadCollectionViaThreadSubscription + public static readonly string ThreadCollectionViaThreadSubscription = "ThreadCollectionViaThreadSubscription"; + /// Member name PostedMessagesInThreads + public static readonly string PostedMessagesInThreads = "PostedMessagesInThreads"; + /// Member name ThreadsInBookmarks + public static readonly string ThreadsInBookmarks = "ThreadsInBookmarks"; + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static UserEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public UserEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for User which data should be fetched into this User object + public UserEntityBase(System.Int32 userID) + { + InitClassFetch(userID, null, null); + } + + /// CTor + /// PK value for User which data should be fetched into this User object + /// the PrefetchPath which defines the graph of objects to fetch as well + public UserEntityBase(System.Int32 userID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(userID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for User which data should be fetched into this User object + /// The custom validator object for this UserEntity + public UserEntityBase(System.Int32 userID, IValidator validator) + { + InitClassFetch(userID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected UserEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _loggedAudits = (SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection)info.GetValue("_loggedAudits", typeof(SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection)); + _alwaysFetchLoggedAudits = info.GetBoolean("_alwaysFetchLoggedAudits"); + _alreadyFetchedLoggedAudits = info.GetBoolean("_alreadyFetchedLoggedAudits"); + _bookmarks = (SD.HnD.DAL.CollectionClasses.BookmarkCollection)info.GetValue("_bookmarks", typeof(SD.HnD.DAL.CollectionClasses.BookmarkCollection)); + _alwaysFetchBookmarks = info.GetBoolean("_alwaysFetchBookmarks"); + _alreadyFetchedBookmarks = info.GetBoolean("_alreadyFetchedBookmarks"); + _iPBansSet = (SD.HnD.DAL.CollectionClasses.IPBanCollection)info.GetValue("_iPBansSet", typeof(SD.HnD.DAL.CollectionClasses.IPBanCollection)); + _alwaysFetchIPBansSet = info.GetBoolean("_alwaysFetchIPBansSet"); + _alreadyFetchedIPBansSet = info.GetBoolean("_alreadyFetchedIPBansSet"); + _postedMessages = (SD.HnD.DAL.CollectionClasses.MessageCollection)info.GetValue("_postedMessages", typeof(SD.HnD.DAL.CollectionClasses.MessageCollection)); + _alwaysFetchPostedMessages = info.GetBoolean("_alwaysFetchPostedMessages"); + _alreadyFetchedPostedMessages = info.GetBoolean("_alreadyFetchedPostedMessages"); + _roleUser = (SD.HnD.DAL.CollectionClasses.RoleUserCollection)info.GetValue("_roleUser", typeof(SD.HnD.DAL.CollectionClasses.RoleUserCollection)); + _alwaysFetchRoleUser = info.GetBoolean("_alwaysFetchRoleUser"); + _alreadyFetchedRoleUser = info.GetBoolean("_alreadyFetchedRoleUser"); + _supportQueueThreadsClaimed = (SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection)info.GetValue("_supportQueueThreadsClaimed", typeof(SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection)); + _alwaysFetchSupportQueueThreadsClaimed = info.GetBoolean("_alwaysFetchSupportQueueThreadsClaimed"); + _alreadyFetchedSupportQueueThreadsClaimed = info.GetBoolean("_alreadyFetchedSupportQueueThreadsClaimed"); + _supportQueueThreadsPlaced = (SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection)info.GetValue("_supportQueueThreadsPlaced", typeof(SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection)); + _alwaysFetchSupportQueueThreadsPlaced = info.GetBoolean("_alwaysFetchSupportQueueThreadsPlaced"); + _alreadyFetchedSupportQueueThreadsPlaced = info.GetBoolean("_alreadyFetchedSupportQueueThreadsPlaced"); + _startedThreads = (SD.HnD.DAL.CollectionClasses.ThreadCollection)info.GetValue("_startedThreads", typeof(SD.HnD.DAL.CollectionClasses.ThreadCollection)); + _alwaysFetchStartedThreads = info.GetBoolean("_alwaysFetchStartedThreads"); + _alreadyFetchedStartedThreads = info.GetBoolean("_alreadyFetchedStartedThreads"); + _threadSubscription = (SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection)info.GetValue("_threadSubscription", typeof(SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection)); + _alwaysFetchThreadSubscription = info.GetBoolean("_alwaysFetchThreadSubscription"); + _alreadyFetchedThreadSubscription = info.GetBoolean("_alreadyFetchedThreadSubscription"); + _startedThreadsInForums = (SD.HnD.DAL.CollectionClasses.ForumCollection)info.GetValue("_startedThreadsInForums", typeof(SD.HnD.DAL.CollectionClasses.ForumCollection)); + _alwaysFetchStartedThreadsInForums = info.GetBoolean("_alwaysFetchStartedThreadsInForums"); + _alreadyFetchedStartedThreadsInForums = info.GetBoolean("_alreadyFetchedStartedThreadsInForums"); + _roles = (SD.HnD.DAL.CollectionClasses.RoleCollection)info.GetValue("_roles", typeof(SD.HnD.DAL.CollectionClasses.RoleCollection)); + _alwaysFetchRoles = info.GetBoolean("_alwaysFetchRoles"); + _alreadyFetchedRoles = info.GetBoolean("_alreadyFetchedRoles"); + _threadCollectionViaThreadSubscription = (SD.HnD.DAL.CollectionClasses.ThreadCollection)info.GetValue("_threadCollectionViaThreadSubscription", typeof(SD.HnD.DAL.CollectionClasses.ThreadCollection)); + _alwaysFetchThreadCollectionViaThreadSubscription = info.GetBoolean("_alwaysFetchThreadCollectionViaThreadSubscription"); + _alreadyFetchedThreadCollectionViaThreadSubscription = info.GetBoolean("_alreadyFetchedThreadCollectionViaThreadSubscription"); + _postedMessagesInThreads = (SD.HnD.DAL.CollectionClasses.ThreadCollection)info.GetValue("_postedMessagesInThreads", typeof(SD.HnD.DAL.CollectionClasses.ThreadCollection)); + _alwaysFetchPostedMessagesInThreads = info.GetBoolean("_alwaysFetchPostedMessagesInThreads"); + _alreadyFetchedPostedMessagesInThreads = info.GetBoolean("_alreadyFetchedPostedMessagesInThreads"); + _threadsInBookmarks = (SD.HnD.DAL.CollectionClasses.ThreadCollection)info.GetValue("_threadsInBookmarks", typeof(SD.HnD.DAL.CollectionClasses.ThreadCollection)); + _alwaysFetchThreadsInBookmarks = info.GetBoolean("_alwaysFetchThreadsInBookmarks"); + _alreadyFetchedThreadsInBookmarks = info.GetBoolean("_alreadyFetchedThreadsInBookmarks"); + _userTitle = (UserTitleEntity)info.GetValue("_userTitle", typeof(UserTitleEntity)); + if(_userTitle!=null) + { + _userTitle.AfterSave+=new EventHandler(OnEntityAfterSave); + } + _userTitleReturnsNewIfNotFound = info.GetBoolean("_userTitleReturnsNewIfNotFound"); + _alwaysFetchUserTitle = info.GetBoolean("_alwaysFetchUserTitle"); + _alreadyFetchedUserTitle = info.GetBoolean("_alreadyFetchedUserTitle"); + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((UserFieldIndex)fieldIndex) + { + case UserFieldIndex.UserTitleID: + DesetupSyncUserTitle(true, false); + _alreadyFetchedUserTitle = false; + break; + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedLoggedAudits = (_loggedAudits.Count > 0); + _alreadyFetchedBookmarks = (_bookmarks.Count > 0); + _alreadyFetchedIPBansSet = (_iPBansSet.Count > 0); + _alreadyFetchedPostedMessages = (_postedMessages.Count > 0); + _alreadyFetchedRoleUser = (_roleUser.Count > 0); + _alreadyFetchedSupportQueueThreadsClaimed = (_supportQueueThreadsClaimed.Count > 0); + _alreadyFetchedSupportQueueThreadsPlaced = (_supportQueueThreadsPlaced.Count > 0); + _alreadyFetchedStartedThreads = (_startedThreads.Count > 0); + _alreadyFetchedThreadSubscription = (_threadSubscription.Count > 0); + _alreadyFetchedStartedThreadsInForums = (_startedThreadsInForums.Count > 0); + _alreadyFetchedRoles = (_roles.Count > 0); + _alreadyFetchedThreadCollectionViaThreadSubscription = (_threadCollectionViaThreadSubscription.Count > 0); + _alreadyFetchedPostedMessagesInThreads = (_postedMessagesInThreads.Count > 0); + _alreadyFetchedThreadsInBookmarks = (_threadsInBookmarks.Count > 0); + _alreadyFetchedUserTitle = (_userTitle != null); + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return UserEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + case "UserTitle": + toReturn.Add(UserEntity.Relations.UserTitleEntityUsingUserTitleID); + break; + case "LoggedAudits": + toReturn.Add(UserEntity.Relations.AuditDataCoreEntityUsingUserID); + break; + case "Bookmarks": + toReturn.Add(UserEntity.Relations.BookmarkEntityUsingUserID); + break; + case "IPBansSet": + toReturn.Add(UserEntity.Relations.IPBanEntityUsingIPBanSetByUserID); + break; + case "PostedMessages": + toReturn.Add(UserEntity.Relations.MessageEntityUsingPostedByUserID); + break; + case "RoleUser": + toReturn.Add(UserEntity.Relations.RoleUserEntityUsingUserID); + break; + case "SupportQueueThreadsClaimed": + toReturn.Add(UserEntity.Relations.SupportQueueThreadEntityUsingClaimedByUserID); + break; + case "SupportQueueThreadsPlaced": + toReturn.Add(UserEntity.Relations.SupportQueueThreadEntityUsingPlacedInQueueByUserID); + break; + case "StartedThreads": + toReturn.Add(UserEntity.Relations.ThreadEntityUsingStartedByUserID); + break; + case "ThreadSubscription": + toReturn.Add(UserEntity.Relations.ThreadSubscriptionEntityUsingUserID); + break; + case "StartedThreadsInForums": + toReturn.Add(UserEntity.Relations.ThreadEntityUsingStartedByUserID, "UserEntity__", "Thread_", JoinHint.None); + toReturn.Add(ThreadEntity.Relations.ForumEntityUsingForumID, "Thread_", string.Empty, JoinHint.None); + break; + case "Roles": + toReturn.Add(UserEntity.Relations.RoleUserEntityUsingUserID, "UserEntity__", "RoleUser_", JoinHint.None); + toReturn.Add(RoleUserEntity.Relations.RoleEntityUsingRoleID, "RoleUser_", string.Empty, JoinHint.None); + break; + case "ThreadCollectionViaThreadSubscription": + toReturn.Add(UserEntity.Relations.ThreadSubscriptionEntityUsingUserID, "UserEntity__", "ThreadSubscription_", JoinHint.None); + toReturn.Add(ThreadSubscriptionEntity.Relations.ThreadEntityUsingThreadID, "ThreadSubscription_", string.Empty, JoinHint.None); + break; + case "PostedMessagesInThreads": + toReturn.Add(UserEntity.Relations.MessageEntityUsingPostedByUserID, "UserEntity__", "Message_", JoinHint.None); + toReturn.Add(MessageEntity.Relations.ThreadEntityUsingThreadID, "Message_", string.Empty, JoinHint.None); + break; + case "ThreadsInBookmarks": + toReturn.Add(UserEntity.Relations.BookmarkEntityUsingUserID, "UserEntity__", "Bookmark_", JoinHint.None); + toReturn.Add(BookmarkEntity.Relations.ThreadEntityUsingThreadID, "Bookmark_", string.Empty, JoinHint.None); + break; + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_loggedAudits", (!this.MarkedForDeletion?_loggedAudits:null)); + info.AddValue("_alwaysFetchLoggedAudits", _alwaysFetchLoggedAudits); + info.AddValue("_alreadyFetchedLoggedAudits", _alreadyFetchedLoggedAudits); + info.AddValue("_bookmarks", (!this.MarkedForDeletion?_bookmarks:null)); + info.AddValue("_alwaysFetchBookmarks", _alwaysFetchBookmarks); + info.AddValue("_alreadyFetchedBookmarks", _alreadyFetchedBookmarks); + info.AddValue("_iPBansSet", (!this.MarkedForDeletion?_iPBansSet:null)); + info.AddValue("_alwaysFetchIPBansSet", _alwaysFetchIPBansSet); + info.AddValue("_alreadyFetchedIPBansSet", _alreadyFetchedIPBansSet); + info.AddValue("_postedMessages", (!this.MarkedForDeletion?_postedMessages:null)); + info.AddValue("_alwaysFetchPostedMessages", _alwaysFetchPostedMessages); + info.AddValue("_alreadyFetchedPostedMessages", _alreadyFetchedPostedMessages); + info.AddValue("_roleUser", (!this.MarkedForDeletion?_roleUser:null)); + info.AddValue("_alwaysFetchRoleUser", _alwaysFetchRoleUser); + info.AddValue("_alreadyFetchedRoleUser", _alreadyFetchedRoleUser); + info.AddValue("_supportQueueThreadsClaimed", (!this.MarkedForDeletion?_supportQueueThreadsClaimed:null)); + info.AddValue("_alwaysFetchSupportQueueThreadsClaimed", _alwaysFetchSupportQueueThreadsClaimed); + info.AddValue("_alreadyFetchedSupportQueueThreadsClaimed", _alreadyFetchedSupportQueueThreadsClaimed); + info.AddValue("_supportQueueThreadsPlaced", (!this.MarkedForDeletion?_supportQueueThreadsPlaced:null)); + info.AddValue("_alwaysFetchSupportQueueThreadsPlaced", _alwaysFetchSupportQueueThreadsPlaced); + info.AddValue("_alreadyFetchedSupportQueueThreadsPlaced", _alreadyFetchedSupportQueueThreadsPlaced); + info.AddValue("_startedThreads", (!this.MarkedForDeletion?_startedThreads:null)); + info.AddValue("_alwaysFetchStartedThreads", _alwaysFetchStartedThreads); + info.AddValue("_alreadyFetchedStartedThreads", _alreadyFetchedStartedThreads); + info.AddValue("_threadSubscription", (!this.MarkedForDeletion?_threadSubscription:null)); + info.AddValue("_alwaysFetchThreadSubscription", _alwaysFetchThreadSubscription); + info.AddValue("_alreadyFetchedThreadSubscription", _alreadyFetchedThreadSubscription); + info.AddValue("_startedThreadsInForums", (!this.MarkedForDeletion?_startedThreadsInForums:null)); + info.AddValue("_alwaysFetchStartedThreadsInForums", _alwaysFetchStartedThreadsInForums); + info.AddValue("_alreadyFetchedStartedThreadsInForums", _alreadyFetchedStartedThreadsInForums); + info.AddValue("_roles", (!this.MarkedForDeletion?_roles:null)); + info.AddValue("_alwaysFetchRoles", _alwaysFetchRoles); + info.AddValue("_alreadyFetchedRoles", _alreadyFetchedRoles); + info.AddValue("_threadCollectionViaThreadSubscription", (!this.MarkedForDeletion?_threadCollectionViaThreadSubscription:null)); + info.AddValue("_alwaysFetchThreadCollectionViaThreadSubscription", _alwaysFetchThreadCollectionViaThreadSubscription); + info.AddValue("_alreadyFetchedThreadCollectionViaThreadSubscription", _alreadyFetchedThreadCollectionViaThreadSubscription); + info.AddValue("_postedMessagesInThreads", (!this.MarkedForDeletion?_postedMessagesInThreads:null)); + info.AddValue("_alwaysFetchPostedMessagesInThreads", _alwaysFetchPostedMessagesInThreads); + info.AddValue("_alreadyFetchedPostedMessagesInThreads", _alreadyFetchedPostedMessagesInThreads); + info.AddValue("_threadsInBookmarks", (!this.MarkedForDeletion?_threadsInBookmarks:null)); + info.AddValue("_alwaysFetchThreadsInBookmarks", _alwaysFetchThreadsInBookmarks); + info.AddValue("_alreadyFetchedThreadsInBookmarks", _alreadyFetchedThreadsInBookmarks); + info.AddValue("_userTitle", (!this.MarkedForDeletion?_userTitle:null)); + info.AddValue("_userTitleReturnsNewIfNotFound", _userTitleReturnsNewIfNotFound); + info.AddValue("_alwaysFetchUserTitle", _alwaysFetchUserTitle); + info.AddValue("_alreadyFetchedUserTitle", _alreadyFetchedUserTitle); + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + case "UserTitle": + _alreadyFetchedUserTitle = true; + this.UserTitle = (UserTitleEntity)entity; + break; + case "LoggedAudits": + _alreadyFetchedLoggedAudits = true; + if(entity!=null) + { + this.LoggedAudits.Add((AuditDataCoreEntity)entity); + } + break; + case "Bookmarks": + _alreadyFetchedBookmarks = true; + if(entity!=null) + { + this.Bookmarks.Add((BookmarkEntity)entity); + } + break; + case "IPBansSet": + _alreadyFetchedIPBansSet = true; + if(entity!=null) + { + this.IPBansSet.Add((IPBanEntity)entity); + } + break; + case "PostedMessages": + _alreadyFetchedPostedMessages = true; + if(entity!=null) + { + this.PostedMessages.Add((MessageEntity)entity); + } + break; + case "RoleUser": + _alreadyFetchedRoleUser = true; + if(entity!=null) + { + this.RoleUser.Add((RoleUserEntity)entity); + } + break; + case "SupportQueueThreadsClaimed": + _alreadyFetchedSupportQueueThreadsClaimed = true; + if(entity!=null) + { + this.SupportQueueThreadsClaimed.Add((SupportQueueThreadEntity)entity); + } + break; + case "SupportQueueThreadsPlaced": + _alreadyFetchedSupportQueueThreadsPlaced = true; + if(entity!=null) + { + this.SupportQueueThreadsPlaced.Add((SupportQueueThreadEntity)entity); + } + break; + case "StartedThreads": + _alreadyFetchedStartedThreads = true; + if(entity!=null) + { + this.StartedThreads.Add((ThreadEntity)entity); + } + break; + case "ThreadSubscription": + _alreadyFetchedThreadSubscription = true; + if(entity!=null) + { + this.ThreadSubscription.Add((ThreadSubscriptionEntity)entity); + } + break; + case "StartedThreadsInForums": + _alreadyFetchedStartedThreadsInForums = true; + if(entity!=null) + { + this.StartedThreadsInForums.Add((ForumEntity)entity); + } + break; + case "Roles": + _alreadyFetchedRoles = true; + if(entity!=null) + { + this.Roles.Add((RoleEntity)entity); + } + break; + case "ThreadCollectionViaThreadSubscription": + _alreadyFetchedThreadCollectionViaThreadSubscription = true; + if(entity!=null) + { + this.ThreadCollectionViaThreadSubscription.Add((ThreadEntity)entity); + } + break; + case "PostedMessagesInThreads": + _alreadyFetchedPostedMessagesInThreads = true; + if(entity!=null) + { + this.PostedMessagesInThreads.Add((ThreadEntity)entity); + } + break; + case "ThreadsInBookmarks": + _alreadyFetchedThreadsInBookmarks = true; + if(entity!=null) + { + this.ThreadsInBookmarks.Add((ThreadEntity)entity); + } + break; + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + case "UserTitle": + SetupSyncUserTitle(relatedEntity); + break; + case "LoggedAudits": + _loggedAudits.Add((AuditDataCoreEntity)relatedEntity); + break; + case "Bookmarks": + _bookmarks.Add((BookmarkEntity)relatedEntity); + break; + case "IPBansSet": + _iPBansSet.Add((IPBanEntity)relatedEntity); + break; + case "PostedMessages": + _postedMessages.Add((MessageEntity)relatedEntity); + break; + case "RoleUser": + _roleUser.Add((RoleUserEntity)relatedEntity); + break; + case "SupportQueueThreadsClaimed": + _supportQueueThreadsClaimed.Add((SupportQueueThreadEntity)relatedEntity); + break; + case "SupportQueueThreadsPlaced": + _supportQueueThreadsPlaced.Add((SupportQueueThreadEntity)relatedEntity); + break; + case "StartedThreads": + _startedThreads.Add((ThreadEntity)relatedEntity); + break; + case "ThreadSubscription": + _threadSubscription.Add((ThreadSubscriptionEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + case "UserTitle": + DesetupSyncUserTitle(false, true); + break; + case "LoggedAudits": + base.PerformRelatedEntityRemoval(_loggedAudits, relatedEntity, signalRelatedEntityManyToOne); + break; + case "Bookmarks": + base.PerformRelatedEntityRemoval(_bookmarks, relatedEntity, signalRelatedEntityManyToOne); + break; + case "IPBansSet": + base.PerformRelatedEntityRemoval(_iPBansSet, relatedEntity, signalRelatedEntityManyToOne); + break; + case "PostedMessages": + base.PerformRelatedEntityRemoval(_postedMessages, relatedEntity, signalRelatedEntityManyToOne); + break; + case "RoleUser": + base.PerformRelatedEntityRemoval(_roleUser, relatedEntity, signalRelatedEntityManyToOne); + break; + case "SupportQueueThreadsClaimed": + base.PerformRelatedEntityRemoval(_supportQueueThreadsClaimed, relatedEntity, signalRelatedEntityManyToOne); + break; + case "SupportQueueThreadsPlaced": + base.PerformRelatedEntityRemoval(_supportQueueThreadsPlaced, relatedEntity, signalRelatedEntityManyToOne); + break; + case "StartedThreads": + base.PerformRelatedEntityRemoval(_startedThreads, relatedEntity, signalRelatedEntityManyToOne); + break; + case "ThreadSubscription": + base.PerformRelatedEntityRemoval(_threadSubscription, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + if(_userTitle!=null) + { + toReturn.Add(_userTitle); + } + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_loggedAudits); + toReturn.Add(_bookmarks); + toReturn.Add(_iPBansSet); + toReturn.Add(_postedMessages); + toReturn.Add(_roleUser); + toReturn.Add(_supportQueueThreadsClaimed); + toReturn.Add(_supportQueueThreadsPlaced); + toReturn.Add(_startedThreads); + toReturn.Add(_threadSubscription); + + return toReturn; + } + + /// Method which will try to fetch the contents for this entity using a unique constraint. + /// All contents of the entity is lost. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// true if succeeded and the contents is read, false otherwise + public bool FetchUsingUCNickName(System.String nickName) + { + return FetchUsingUCNickName( nickName, null, null, null); + } + + /// Method which will try to fetch the contents for this entity using a unique constraint. + /// All contents of the entity is lost. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// the PrefetchPath which defines the graph of objects to fetch as well + /// true if succeeded and the contents is read, false otherwise + public bool FetchUsingUCNickName(System.String nickName, IPrefetchPath prefetchPathToUse) + { + return FetchUsingUCNickName( nickName, prefetchPathToUse, null, null); + } + + /// Method which will try to fetch the contents for this entity using a unique constraint. + /// All contents of the entity is lost. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// true if succeeded and the contents is read, false otherwise + public bool FetchUsingUCNickName(System.String nickName, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return FetchUsingUCNickName( nickName, prefetchPathToUse, contextToUse, null); + } + + /// Method which will try to fetch the contents for this entity using a unique constraint. + /// All contents of the entity is lost. + /// Value for a field in the UniqueConstraint, which is used to retrieve the contents. + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// true if succeeded and the contents is read, false otherwise + public bool FetchUsingUCNickName(System.String nickName, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + UserDAO dao = (UserDAO)CreateDAOInstance(); + dao.FetchUserUsingUCNickName(this, base.Transaction, nickName, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for User which data should be fetched into this User object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userID) + { + return FetchUsingPK(userID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for User which data should be fetched into this User object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(userID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for User which data should be fetched into this User object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(userID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for User which data should be fetched into this User object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(userID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.UserID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(UserFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(UserFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new UserRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'AuditDataCoreEntity' + public SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection GetMultiLoggedAudits(bool forceFetch) + { + return GetMultiLoggedAudits(forceFetch, _loggedAudits.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'AuditDataCoreEntity' + public SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection GetMultiLoggedAudits(bool forceFetch, IPredicateExpression filter) + { + return GetMultiLoggedAudits(forceFetch, _loggedAudits.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection GetMultiLoggedAudits(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiLoggedAudits(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection GetMultiLoggedAudits(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedLoggedAudits || forceFetch || _alwaysFetchLoggedAudits) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_loggedAudits.ParticipatesInTransaction) + { + base.Transaction.Add(_loggedAudits); + } + } + _loggedAudits.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _loggedAudits.EntityFactoryToUse = entityFactoryToUse; + } + _loggedAudits.GetMultiManyToOne(null, this, filter); + _loggedAudits.SuppressClearInGetMulti=false; + _alreadyFetchedLoggedAudits = true; + } + return _loggedAudits; + } + + /// Sets the collection parameters for the collection for 'LoggedAudits'. These settings will be taken into account + /// when the property LoggedAudits is requested or GetMultiLoggedAudits is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersLoggedAudits(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _loggedAudits.SortClauses=sortClauses; + _loggedAudits.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'BookmarkEntity' + public SD.HnD.DAL.CollectionClasses.BookmarkCollection GetMultiBookmarks(bool forceFetch) + { + return GetMultiBookmarks(forceFetch, _bookmarks.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'BookmarkEntity' + public SD.HnD.DAL.CollectionClasses.BookmarkCollection GetMultiBookmarks(bool forceFetch, IPredicateExpression filter) + { + return GetMultiBookmarks(forceFetch, _bookmarks.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.BookmarkCollection GetMultiBookmarks(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiBookmarks(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.BookmarkCollection GetMultiBookmarks(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedBookmarks || forceFetch || _alwaysFetchBookmarks) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_bookmarks.ParticipatesInTransaction) + { + base.Transaction.Add(_bookmarks); + } + } + _bookmarks.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _bookmarks.EntityFactoryToUse = entityFactoryToUse; + } + _bookmarks.GetMultiManyToOne(null, this, filter); + _bookmarks.SuppressClearInGetMulti=false; + _alreadyFetchedBookmarks = true; + } + return _bookmarks; + } + + /// Sets the collection parameters for the collection for 'Bookmarks'. These settings will be taken into account + /// when the property Bookmarks is requested or GetMultiBookmarks is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersBookmarks(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _bookmarks.SortClauses=sortClauses; + _bookmarks.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'IPBanEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'IPBanEntity' + public SD.HnD.DAL.CollectionClasses.IPBanCollection GetMultiIPBansSet(bool forceFetch) + { + return GetMultiIPBansSet(forceFetch, _iPBansSet.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'IPBanEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'IPBanEntity' + public SD.HnD.DAL.CollectionClasses.IPBanCollection GetMultiIPBansSet(bool forceFetch, IPredicateExpression filter) + { + return GetMultiIPBansSet(forceFetch, _iPBansSet.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'IPBanEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.IPBanCollection GetMultiIPBansSet(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiIPBansSet(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'IPBanEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.IPBanCollection GetMultiIPBansSet(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedIPBansSet || forceFetch || _alwaysFetchIPBansSet) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_iPBansSet.ParticipatesInTransaction) + { + base.Transaction.Add(_iPBansSet); + } + } + _iPBansSet.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _iPBansSet.EntityFactoryToUse = entityFactoryToUse; + } + _iPBansSet.GetMultiManyToOne(this, filter); + _iPBansSet.SuppressClearInGetMulti=false; + _alreadyFetchedIPBansSet = true; + } + return _iPBansSet; + } + + /// Sets the collection parameters for the collection for 'IPBansSet'. These settings will be taken into account + /// when the property IPBansSet is requested or GetMultiIPBansSet is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersIPBansSet(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _iPBansSet.SortClauses=sortClauses; + _iPBansSet.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'MessageEntity' + public SD.HnD.DAL.CollectionClasses.MessageCollection GetMultiPostedMessages(bool forceFetch) + { + return GetMultiPostedMessages(forceFetch, _postedMessages.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'MessageEntity' + public SD.HnD.DAL.CollectionClasses.MessageCollection GetMultiPostedMessages(bool forceFetch, IPredicateExpression filter) + { + return GetMultiPostedMessages(forceFetch, _postedMessages.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.MessageCollection GetMultiPostedMessages(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiPostedMessages(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.MessageCollection GetMultiPostedMessages(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedPostedMessages || forceFetch || _alwaysFetchPostedMessages) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_postedMessages.ParticipatesInTransaction) + { + base.Transaction.Add(_postedMessages); + } + } + _postedMessages.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _postedMessages.EntityFactoryToUse = entityFactoryToUse; + } + _postedMessages.GetMultiManyToOne(null, this, filter); + _postedMessages.SuppressClearInGetMulti=false; + _alreadyFetchedPostedMessages = true; + } + return _postedMessages; + } + + /// Sets the collection parameters for the collection for 'PostedMessages'. These settings will be taken into account + /// when the property PostedMessages is requested or GetMultiPostedMessages is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersPostedMessages(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _postedMessages.SortClauses=sortClauses; + _postedMessages.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleUserEntity' + public SD.HnD.DAL.CollectionClasses.RoleUserCollection GetMultiRoleUser(bool forceFetch) + { + return GetMultiRoleUser(forceFetch, _roleUser.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'RoleUserEntity' + public SD.HnD.DAL.CollectionClasses.RoleUserCollection GetMultiRoleUser(bool forceFetch, IPredicateExpression filter) + { + return GetMultiRoleUser(forceFetch, _roleUser.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleUserCollection GetMultiRoleUser(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiRoleUser(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.RoleUserCollection GetMultiRoleUser(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedRoleUser || forceFetch || _alwaysFetchRoleUser) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_roleUser.ParticipatesInTransaction) + { + base.Transaction.Add(_roleUser); + } + } + _roleUser.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _roleUser.EntityFactoryToUse = entityFactoryToUse; + } + _roleUser.GetMultiManyToOne(null, this, filter); + _roleUser.SuppressClearInGetMulti=false; + _alreadyFetchedRoleUser = true; + } + return _roleUser; + } + + /// Sets the collection parameters for the collection for 'RoleUser'. These settings will be taken into account + /// when the property RoleUser is requested or GetMultiRoleUser is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersRoleUser(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _roleUser.SortClauses=sortClauses; + _roleUser.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'SupportQueueThreadEntity' + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreadsClaimed(bool forceFetch) + { + return GetMultiSupportQueueThreadsClaimed(forceFetch, _supportQueueThreadsClaimed.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'SupportQueueThreadEntity' + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreadsClaimed(bool forceFetch, IPredicateExpression filter) + { + return GetMultiSupportQueueThreadsClaimed(forceFetch, _supportQueueThreadsClaimed.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreadsClaimed(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiSupportQueueThreadsClaimed(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreadsClaimed(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedSupportQueueThreadsClaimed || forceFetch || _alwaysFetchSupportQueueThreadsClaimed) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_supportQueueThreadsClaimed.ParticipatesInTransaction) + { + base.Transaction.Add(_supportQueueThreadsClaimed); + } + } + _supportQueueThreadsClaimed.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _supportQueueThreadsClaimed.EntityFactoryToUse = entityFactoryToUse; + } + _supportQueueThreadsClaimed.GetMultiManyToOne(null, this, null, filter); + _supportQueueThreadsClaimed.SuppressClearInGetMulti=false; + _alreadyFetchedSupportQueueThreadsClaimed = true; + } + return _supportQueueThreadsClaimed; + } + + /// Sets the collection parameters for the collection for 'SupportQueueThreadsClaimed'. These settings will be taken into account + /// when the property SupportQueueThreadsClaimed is requested or GetMultiSupportQueueThreadsClaimed is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersSupportQueueThreadsClaimed(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _supportQueueThreadsClaimed.SortClauses=sortClauses; + _supportQueueThreadsClaimed.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'SupportQueueThreadEntity' + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreadsPlaced(bool forceFetch) + { + return GetMultiSupportQueueThreadsPlaced(forceFetch, _supportQueueThreadsPlaced.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'SupportQueueThreadEntity' + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreadsPlaced(bool forceFetch, IPredicateExpression filter) + { + return GetMultiSupportQueueThreadsPlaced(forceFetch, _supportQueueThreadsPlaced.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreadsPlaced(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiSupportQueueThreadsPlaced(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection GetMultiSupportQueueThreadsPlaced(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedSupportQueueThreadsPlaced || forceFetch || _alwaysFetchSupportQueueThreadsPlaced) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_supportQueueThreadsPlaced.ParticipatesInTransaction) + { + base.Transaction.Add(_supportQueueThreadsPlaced); + } + } + _supportQueueThreadsPlaced.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _supportQueueThreadsPlaced.EntityFactoryToUse = entityFactoryToUse; + } + _supportQueueThreadsPlaced.GetMultiManyToOne(null, null, this, filter); + _supportQueueThreadsPlaced.SuppressClearInGetMulti=false; + _alreadyFetchedSupportQueueThreadsPlaced = true; + } + return _supportQueueThreadsPlaced; + } + + /// Sets the collection parameters for the collection for 'SupportQueueThreadsPlaced'. These settings will be taken into account + /// when the property SupportQueueThreadsPlaced is requested or GetMultiSupportQueueThreadsPlaced is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersSupportQueueThreadsPlaced(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _supportQueueThreadsPlaced.SortClauses=sortClauses; + _supportQueueThreadsPlaced.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ThreadEntity' + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiStartedThreads(bool forceFetch) + { + return GetMultiStartedThreads(forceFetch, _startedThreads.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ThreadEntity' + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiStartedThreads(bool forceFetch, IPredicateExpression filter) + { + return GetMultiStartedThreads(forceFetch, _startedThreads.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiStartedThreads(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiStartedThreads(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiStartedThreads(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedStartedThreads || forceFetch || _alwaysFetchStartedThreads) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_startedThreads.ParticipatesInTransaction) + { + base.Transaction.Add(_startedThreads); + } + } + _startedThreads.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _startedThreads.EntityFactoryToUse = entityFactoryToUse; + } + _startedThreads.GetMultiManyToOne(null, this, filter); + _startedThreads.SuppressClearInGetMulti=false; + _alreadyFetchedStartedThreads = true; + } + return _startedThreads; + } + + /// Sets the collection parameters for the collection for 'StartedThreads'. These settings will be taken into account + /// when the property StartedThreads is requested or GetMultiStartedThreads is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersStartedThreads(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _startedThreads.SortClauses=sortClauses; + _startedThreads.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ThreadSubscriptionEntity' + public SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection GetMultiThreadSubscription(bool forceFetch) + { + return GetMultiThreadSubscription(forceFetch, _threadSubscription.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'ThreadSubscriptionEntity' + public SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection GetMultiThreadSubscription(bool forceFetch, IPredicateExpression filter) + { + return GetMultiThreadSubscription(forceFetch, _threadSubscription.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection GetMultiThreadSubscription(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiThreadSubscription(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection GetMultiThreadSubscription(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedThreadSubscription || forceFetch || _alwaysFetchThreadSubscription) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_threadSubscription.ParticipatesInTransaction) + { + base.Transaction.Add(_threadSubscription); + } + } + _threadSubscription.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _threadSubscription.EntityFactoryToUse = entityFactoryToUse; + } + _threadSubscription.GetMultiManyToOne(null, this, filter); + _threadSubscription.SuppressClearInGetMulti=false; + _alreadyFetchedThreadSubscription = true; + } + return _threadSubscription; + } + + /// Sets the collection parameters for the collection for 'ThreadSubscription'. These settings will be taken into account + /// when the property ThreadSubscription is requested or GetMultiThreadSubscription is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersThreadSubscription(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _threadSubscription.SortClauses=sortClauses; + _threadSubscription.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ForumEntity' + public SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiStartedThreadsInForums(bool forceFetch) + { + return GetMultiStartedThreadsInForums(forceFetch, _startedThreadsInForums.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ForumCollection GetMultiStartedThreadsInForums(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedStartedThreadsInForums || forceFetch || _alwaysFetchStartedThreadsInForums) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_startedThreadsInForums.ParticipatesInTransaction) + { + base.Transaction.Add(_startedThreadsInForums); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(UserFields.UserID, ComparisonOperator.Equal, this.UserID, "UserEntity__")); + _startedThreadsInForums.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _startedThreadsInForums.EntityFactoryToUse = entityFactoryToUse; + } + _startedThreadsInForums.GetMulti(filter, GetRelationsForField("StartedThreadsInForums")); + _startedThreadsInForums.SuppressClearInGetMulti=false; + _alreadyFetchedStartedThreadsInForums = true; + } + return _startedThreadsInForums; + } + + /// Sets the collection parameters for the collection for 'StartedThreadsInForums'. These settings will be taken into account + /// when the property StartedThreadsInForums is requested or GetMultiStartedThreadsInForums is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersStartedThreadsInForums(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _startedThreadsInForums.SortClauses=sortClauses; + _startedThreadsInForums.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'RoleEntity' + public SD.HnD.DAL.CollectionClasses.RoleCollection GetMultiRoles(bool forceFetch) + { + return GetMultiRoles(forceFetch, _roles.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.RoleCollection GetMultiRoles(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedRoles || forceFetch || _alwaysFetchRoles) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_roles.ParticipatesInTransaction) + { + base.Transaction.Add(_roles); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(UserFields.UserID, ComparisonOperator.Equal, this.UserID, "UserEntity__")); + _roles.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _roles.EntityFactoryToUse = entityFactoryToUse; + } + _roles.GetMulti(filter, GetRelationsForField("Roles")); + _roles.SuppressClearInGetMulti=false; + _alreadyFetchedRoles = true; + } + return _roles; + } + + /// Sets the collection parameters for the collection for 'Roles'. These settings will be taken into account + /// when the property Roles is requested or GetMultiRoles is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersRoles(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _roles.SortClauses=sortClauses; + _roles.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ThreadEntity' + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiThreadCollectionViaThreadSubscription(bool forceFetch) + { + return GetMultiThreadCollectionViaThreadSubscription(forceFetch, _threadCollectionViaThreadSubscription.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiThreadCollectionViaThreadSubscription(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedThreadCollectionViaThreadSubscription || forceFetch || _alwaysFetchThreadCollectionViaThreadSubscription) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_threadCollectionViaThreadSubscription.ParticipatesInTransaction) + { + base.Transaction.Add(_threadCollectionViaThreadSubscription); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(UserFields.UserID, ComparisonOperator.Equal, this.UserID, "UserEntity__")); + _threadCollectionViaThreadSubscription.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _threadCollectionViaThreadSubscription.EntityFactoryToUse = entityFactoryToUse; + } + _threadCollectionViaThreadSubscription.GetMulti(filter, GetRelationsForField("ThreadCollectionViaThreadSubscription")); + _threadCollectionViaThreadSubscription.SuppressClearInGetMulti=false; + _alreadyFetchedThreadCollectionViaThreadSubscription = true; + } + return _threadCollectionViaThreadSubscription; + } + + /// Sets the collection parameters for the collection for 'ThreadCollectionViaThreadSubscription'. These settings will be taken into account + /// when the property ThreadCollectionViaThreadSubscription is requested or GetMultiThreadCollectionViaThreadSubscription is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersThreadCollectionViaThreadSubscription(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _threadCollectionViaThreadSubscription.SortClauses=sortClauses; + _threadCollectionViaThreadSubscription.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ThreadEntity' + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiPostedMessagesInThreads(bool forceFetch) + { + return GetMultiPostedMessagesInThreads(forceFetch, _postedMessagesInThreads.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiPostedMessagesInThreads(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedPostedMessagesInThreads || forceFetch || _alwaysFetchPostedMessagesInThreads) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_postedMessagesInThreads.ParticipatesInTransaction) + { + base.Transaction.Add(_postedMessagesInThreads); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(UserFields.UserID, ComparisonOperator.Equal, this.UserID, "UserEntity__")); + _postedMessagesInThreads.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _postedMessagesInThreads.EntityFactoryToUse = entityFactoryToUse; + } + _postedMessagesInThreads.GetMulti(filter, GetRelationsForField("PostedMessagesInThreads")); + _postedMessagesInThreads.SuppressClearInGetMulti=false; + _alreadyFetchedPostedMessagesInThreads = true; + } + return _postedMessagesInThreads; + } + + /// Sets the collection parameters for the collection for 'PostedMessagesInThreads'. These settings will be taken into account + /// when the property PostedMessagesInThreads is requested or GetMultiPostedMessagesInThreads is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersPostedMessagesInThreads(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _postedMessagesInThreads.SortClauses=sortClauses; + _postedMessagesInThreads.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'ThreadEntity' + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiThreadsInBookmarks(bool forceFetch) + { + return GetMultiThreadsInBookmarks(forceFetch, _threadsInBookmarks.EntityFactoryToUse); + } + + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToMany() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.ThreadCollection GetMultiThreadsInBookmarks(bool forceFetch, IEntityFactory entityFactoryToUse) + { + if( ( !_alreadyFetchedThreadsInBookmarks || forceFetch || _alwaysFetchThreadsInBookmarks) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_threadsInBookmarks.ParticipatesInTransaction) + { + base.Transaction.Add(_threadsInBookmarks); + } + } + IPredicateExpression filter = new PredicateExpression(); + filter.Add(new FieldCompareValuePredicate(UserFields.UserID, ComparisonOperator.Equal, this.UserID, "UserEntity__")); + _threadsInBookmarks.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _threadsInBookmarks.EntityFactoryToUse = entityFactoryToUse; + } + _threadsInBookmarks.GetMulti(filter, GetRelationsForField("ThreadsInBookmarks")); + _threadsInBookmarks.SuppressClearInGetMulti=false; + _alreadyFetchedThreadsInBookmarks = true; + } + return _threadsInBookmarks; + } + + /// Sets the collection parameters for the collection for 'ThreadsInBookmarks'. These settings will be taken into account + /// when the property ThreadsInBookmarks is requested or GetMultiThreadsInBookmarks is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersThreadsInBookmarks(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _threadsInBookmarks.SortClauses=sortClauses; + _threadsInBookmarks.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + /// Retrieves the related entity of type 'UserTitleEntity', using a relation of type 'n:1' + /// A fetched entity of type 'UserTitleEntity' which is related to this entity. + public UserTitleEntity GetSingleUserTitle() + { + return GetSingleUserTitle(false); + } + + /// Retrieves the related entity of type 'UserTitleEntity', using a relation of type 'n:1' + /// if true, it will discard any changes currently in the currently loaded related entity and will refetch the entity from the persistent storage + /// A fetched entity of type 'UserTitleEntity' which is related to this entity. + public virtual UserTitleEntity GetSingleUserTitle(bool forceFetch) + { + if( ( !_alreadyFetchedUserTitle || forceFetch || _alwaysFetchUserTitle) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + bool performLazyLoading = base.CheckIfLazyLoadingShouldOccur(UserEntity.Relations.UserTitleEntityUsingUserTitleID); + + UserTitleEntity newEntity = new UserTitleEntity(); + if(base.ParticipatesInTransaction) + { + base.Transaction.Add(newEntity); + } + bool fetchResult = false; + if(performLazyLoading) + { + fetchResult = newEntity.FetchUsingPK(this.UserTitleID); + } + if(fetchResult) + { + if(base.ActiveContext!=null) + { + newEntity = (UserTitleEntity)base.ActiveContext.Get(newEntity); + } + this.UserTitle = newEntity; + } + else + { + if(_userTitleReturnsNewIfNotFound) + { + if(performLazyLoading || (!performLazyLoading && (_userTitle == null))) + { + this.UserTitle = newEntity; + } + } + else + { + this.UserTitle = null; + } + } + _alreadyFetchedUserTitle = fetchResult; + if(base.ParticipatesInTransaction && !fetchResult) + { + base.Transaction.Remove(newEntity); + } + } + return _userTitle; + } + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + UserDAO dao = (UserDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _loggedAudits.ActiveContext = base.ActiveContext; + _bookmarks.ActiveContext = base.ActiveContext; + _iPBansSet.ActiveContext = base.ActiveContext; + _postedMessages.ActiveContext = base.ActiveContext; + _roleUser.ActiveContext = base.ActiveContext; + _supportQueueThreadsClaimed.ActiveContext = base.ActiveContext; + _supportQueueThreadsPlaced.ActiveContext = base.ActiveContext; + _startedThreads.ActiveContext = base.ActiveContext; + _threadSubscription.ActiveContext = base.ActiveContext; + _startedThreadsInForums.ActiveContext = base.ActiveContext; + _roles.ActiveContext = base.ActiveContext; + _threadCollectionViaThreadSubscription.ActiveContext = base.ActiveContext; + _postedMessagesInThreads.ActiveContext = base.ActiveContext; + _threadsInBookmarks.ActiveContext = base.ActiveContext; + if(_userTitle!=null) + { + _userTitle.ActiveContext = base.ActiveContext; + } + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + UserDAO dao = (UserDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + UserDAO dao = (UserDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + toReturn.Add("UserTitle", _userTitle); + toReturn.Add("LoggedAudits", _loggedAudits); + toReturn.Add("Bookmarks", _bookmarks); + toReturn.Add("IPBansSet", _iPBansSet); + toReturn.Add("PostedMessages", _postedMessages); + toReturn.Add("RoleUser", _roleUser); + toReturn.Add("SupportQueueThreadsClaimed", _supportQueueThreadsClaimed); + toReturn.Add("SupportQueueThreadsPlaced", _supportQueueThreadsPlaced); + toReturn.Add("StartedThreads", _startedThreads); + toReturn.Add("ThreadSubscription", _threadSubscription); + toReturn.Add("StartedThreadsInForums", _startedThreadsInForums); + toReturn.Add("Roles", _roles); + toReturn.Add("ThreadCollectionViaThreadSubscription", _threadCollectionViaThreadSubscription); + toReturn.Add("PostedMessagesInThreads", _postedMessagesInThreads); + toReturn.Add("ThreadsInBookmarks", _threadsInBookmarks); + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for User which data should be fetched into this User object + /// The validator object for this UserEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 userID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(userID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _loggedAudits = new SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection(new AuditDataCoreEntityFactory()); + _loggedAudits.SetContainingEntityInfo(this, "UserAudited"); + _alwaysFetchLoggedAudits = false; + _alreadyFetchedLoggedAudits = false; + _bookmarks = new SD.HnD.DAL.CollectionClasses.BookmarkCollection(new BookmarkEntityFactory()); + _bookmarks.SetContainingEntityInfo(this, "User"); + _alwaysFetchBookmarks = false; + _alreadyFetchedBookmarks = false; + _iPBansSet = new SD.HnD.DAL.CollectionClasses.IPBanCollection(new IPBanEntityFactory()); + _iPBansSet.SetContainingEntityInfo(this, "SetByUser"); + _alwaysFetchIPBansSet = false; + _alreadyFetchedIPBansSet = false; + _postedMessages = new SD.HnD.DAL.CollectionClasses.MessageCollection(new MessageEntityFactory()); + _postedMessages.SetContainingEntityInfo(this, "PostedByUser"); + _alwaysFetchPostedMessages = false; + _alreadyFetchedPostedMessages = false; + _roleUser = new SD.HnD.DAL.CollectionClasses.RoleUserCollection(new RoleUserEntityFactory()); + _roleUser.SetContainingEntityInfo(this, "User"); + _alwaysFetchRoleUser = false; + _alreadyFetchedRoleUser = false; + _supportQueueThreadsClaimed = new SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection(new SupportQueueThreadEntityFactory()); + _supportQueueThreadsClaimed.SetContainingEntityInfo(this, "ClaimedByUser"); + _alwaysFetchSupportQueueThreadsClaimed = false; + _alreadyFetchedSupportQueueThreadsClaimed = false; + _supportQueueThreadsPlaced = new SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection(new SupportQueueThreadEntityFactory()); + _supportQueueThreadsPlaced.SetContainingEntityInfo(this, "PlacedInQueueByUser"); + _alwaysFetchSupportQueueThreadsPlaced = false; + _alreadyFetchedSupportQueueThreadsPlaced = false; + _startedThreads = new SD.HnD.DAL.CollectionClasses.ThreadCollection(new ThreadEntityFactory()); + _startedThreads.SetContainingEntityInfo(this, "UserWhoStartedThread"); + _alwaysFetchStartedThreads = false; + _alreadyFetchedStartedThreads = false; + _threadSubscription = new SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection(new ThreadSubscriptionEntityFactory()); + _threadSubscription.SetContainingEntityInfo(this, "User"); + _alwaysFetchThreadSubscription = false; + _alreadyFetchedThreadSubscription = false; + _startedThreadsInForums = new SD.HnD.DAL.CollectionClasses.ForumCollection(new ForumEntityFactory()); + _alwaysFetchStartedThreadsInForums = false; + _alreadyFetchedStartedThreadsInForums = false; + _roles = new SD.HnD.DAL.CollectionClasses.RoleCollection(new RoleEntityFactory()); + _alwaysFetchRoles = false; + _alreadyFetchedRoles = false; + _threadCollectionViaThreadSubscription = new SD.HnD.DAL.CollectionClasses.ThreadCollection(new ThreadEntityFactory()); + _alwaysFetchThreadCollectionViaThreadSubscription = false; + _alreadyFetchedThreadCollectionViaThreadSubscription = false; + _postedMessagesInThreads = new SD.HnD.DAL.CollectionClasses.ThreadCollection(new ThreadEntityFactory()); + _alwaysFetchPostedMessagesInThreads = false; + _alreadyFetchedPostedMessagesInThreads = false; + _threadsInBookmarks = new SD.HnD.DAL.CollectionClasses.ThreadCollection(new ThreadEntityFactory()); + _alwaysFetchThreadsInBookmarks = false; + _alreadyFetchedThreadsInBookmarks = false; + _userTitle = null; + _userTitleReturnsNewIfNotFound = true; + _alwaysFetchUserTitle = false; + _alreadyFetchedUserTitle = false; + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("UserID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("NickName", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Password", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IsBanned", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IPNumber", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Signature", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("IconURL", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("EmailAddress", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("UserTitleID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("DateOfBirth", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Occupation", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Location", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("Website", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("SignatureAsHTML", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("JoinDate", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AmountOfPostings", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("EmailAddressIsPublic", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("LastVisitedDate", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("AutoSubscribeToThread", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("DefaultNumberOfMessagesPerPage", fieldHashtable); + } + #endregion + + + /// Removes the sync logic for member _userTitle + /// If set to true, it will call the related entity's UnsetRelatedEntity method + /// if set to true it will also reset the FK fields pointing to the related entity + private void DesetupSyncUserTitle(bool signalRelatedEntity, bool resetFKFields) + { + base.PerformDesetupSyncRelatedEntity( _userTitle, new PropertyChangedEventHandler( OnUserTitlePropertyChanged ), "UserTitle", UserEntity.Relations.UserTitleEntityUsingUserTitleID, true, signalRelatedEntity, "Users", resetFKFields, new int[] { (int)UserFieldIndex.UserTitleID } ); + _userTitle = null; + } + + /// setups the sync logic for member _userTitle + /// Instance to set as the related entity of type entityType + private void SetupSyncUserTitle(IEntity relatedEntity) + { + if(_userTitle!=relatedEntity) + { + DesetupSyncUserTitle(true, true); + _userTitle = (UserTitleEntity)relatedEntity; + base.PerformSetupSyncRelatedEntity( _userTitle, new PropertyChangedEventHandler( OnUserTitlePropertyChanged ), "UserTitle", UserEntity.Relations.UserTitleEntityUsingUserTitleID, true, ref _alreadyFetchedUserTitle, new string[] { } ); + } + } + + /// Handles property change events of properties in a related entity. + /// + /// + private void OnUserTitlePropertyChanged( object sender, PropertyChangedEventArgs e ) + { + switch( e.PropertyName ) + { + default: + break; + } + } + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for User which data should be fetched into this User object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 userID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)UserFieldIndex.UserID].ForcedCurrentValueWrite(userID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateUserDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new UserEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static UserRelations Relations + { + get { return new UserRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'AuditDataCore' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathLoggedAudits + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection(), + (IEntityRelation)GetRelationsForField("LoggedAudits")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.AuditDataCoreEntity, 0, null, null, null, "LoggedAudits", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Bookmark' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathBookmarks + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.BookmarkCollection(), + (IEntityRelation)GetRelationsForField("Bookmarks")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.BookmarkEntity, 0, null, null, null, "Bookmarks", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'IPBan' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathIPBansSet + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.IPBanCollection(), + (IEntityRelation)GetRelationsForField("IPBansSet")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.IPBanEntity, 0, null, null, null, "IPBansSet", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Message' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathPostedMessages + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.MessageCollection(), + (IEntityRelation)GetRelationsForField("PostedMessages")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.MessageEntity, 0, null, null, null, "PostedMessages", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'RoleUser' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoleUser + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleUserCollection(), + (IEntityRelation)GetRelationsForField("RoleUser")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.RoleUserEntity, 0, null, null, null, "RoleUser", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'SupportQueueThread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSupportQueueThreadsClaimed + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection(), + (IEntityRelation)GetRelationsForField("SupportQueueThreadsClaimed")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity, 0, null, null, null, "SupportQueueThreadsClaimed", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'SupportQueueThread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathSupportQueueThreadsPlaced + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection(), + (IEntityRelation)GetRelationsForField("SupportQueueThreadsPlaced")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.SupportQueueThreadEntity, 0, null, null, null, "SupportQueueThreadsPlaced", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathStartedThreads + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), + (IEntityRelation)GetRelationsForField("StartedThreads")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, null, "StartedThreads", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'ThreadSubscription' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThreadSubscription + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection(), + (IEntityRelation)GetRelationsForField("ThreadSubscription")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.ThreadSubscriptionEntity, 0, null, null, null, "ThreadSubscription", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Forum' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathStartedThreadsInForums + { + get + { + IEntityRelation intermediateRelation = UserEntity.Relations.ThreadEntityUsingStartedByUserID; + intermediateRelation.SetAliases(string.Empty, "Thread_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ForumCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.ForumEntity, 0, null, null, GetRelationsForField("StartedThreadsInForums"), "StartedThreadsInForums", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Role' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathRoles + { + get + { + IEntityRelation intermediateRelation = UserEntity.Relations.RoleUserEntityUsingUserID; + intermediateRelation.SetAliases(string.Empty, "RoleUser_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.RoleCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.RoleEntity, 0, null, null, GetRelationsForField("Roles"), "Roles", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThreadCollectionViaThreadSubscription + { + get + { + IEntityRelation intermediateRelation = UserEntity.Relations.ThreadSubscriptionEntityUsingUserID; + intermediateRelation.SetAliases(string.Empty, "ThreadSubscription_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, GetRelationsForField("ThreadCollectionViaThreadSubscription"), "ThreadCollectionViaThreadSubscription", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathPostedMessagesInThreads + { + get + { + IEntityRelation intermediateRelation = UserEntity.Relations.MessageEntityUsingPostedByUserID; + intermediateRelation.SetAliases(string.Empty, "Message_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, GetRelationsForField("PostedMessagesInThreads"), "PostedMessagesInThreads", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'Thread' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathThreadsInBookmarks + { + get + { + IEntityRelation intermediateRelation = UserEntity.Relations.BookmarkEntityUsingUserID; + intermediateRelation.SetAliases(string.Empty, "Bookmark_"); + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.ThreadCollection(), intermediateRelation, + (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.ThreadEntity, 0, null, null, GetRelationsForField("ThreadsInBookmarks"), "ThreadsInBookmarks", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToMany); + } + } + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'UserTitle' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUserTitle + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserTitleCollection(), + (IEntityRelation)GetRelationsForField("UserTitle")[0], (int)SD.HnD.DAL.EntityType.UserEntity, (int)SD.HnD.DAL.EntityType.UserTitleEntity, 0, null, null, null, "UserTitle", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne); + } + } + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "UserEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return UserEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return UserEntity.FieldsCustomProperties;} + } + + /// The UserID property of the Entity User

+ ///
+ /// Mapped on table field: "User"."UserID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 UserID + { + get { return (System.Int32)GetValue((int)UserFieldIndex.UserID, true); } + set { SetValue((int)UserFieldIndex.UserID, value, true); } + } + /// The NickName property of the Entity User

+ ///
+ /// Mapped on table field: "User"."NickName"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 20
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String NickName + { + get { return (System.String)GetValue((int)UserFieldIndex.NickName, true); } + set { SetValue((int)UserFieldIndex.NickName, value, true); } + } + /// The Password property of the Entity User

+ ///
+ /// Mapped on table field: "User"."Password"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 30
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String Password + { + get { return (System.String)GetValue((int)UserFieldIndex.Password, true); } + set { SetValue((int)UserFieldIndex.Password, value, true); } + } + /// The IsBanned property of the Entity User

+ ///
+ /// Mapped on table field: "User"."IsBanned"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Boolean IsBanned + { + get { return (System.Boolean)GetValue((int)UserFieldIndex.IsBanned, true); } + set { SetValue((int)UserFieldIndex.IsBanned, value, true); } + } + /// The IPNumber property of the Entity User

+ ///
+ /// Mapped on table field: "User"."IPNumber"
+ /// Table field type characteristics (type, precision, scale, length): VarChar, 0, 0, 25
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String IPNumber + { + get { return (System.String)GetValue((int)UserFieldIndex.IPNumber, true); } + set { SetValue((int)UserFieldIndex.IPNumber, value, true); } + } + /// The Signature property of the Entity User

+ ///
+ /// Mapped on table field: "User"."Signature"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 250
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String Signature + { + get { return (System.String)GetValue((int)UserFieldIndex.Signature, true); } + set { SetValue((int)UserFieldIndex.Signature, value, true); } + } + /// The IconURL property of the Entity User

+ ///
+ /// Mapped on table field: "User"."IconURL"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 250
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String IconURL + { + get { return (System.String)GetValue((int)UserFieldIndex.IconURL, true); } + set { SetValue((int)UserFieldIndex.IconURL, value, true); } + } + /// The EmailAddress property of the Entity User

+ ///
+ /// Mapped on table field: "User"."EmailAddress"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 200
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String EmailAddress + { + get { return (System.String)GetValue((int)UserFieldIndex.EmailAddress, true); } + set { SetValue((int)UserFieldIndex.EmailAddress, value, true); } + } + /// The UserTitleID property of the Entity User

+ ///
+ /// Mapped on table field: "User"."UserTitleID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.Int32 UserTitleID + { + get { return (System.Int32)GetValue((int)UserFieldIndex.UserTitleID, true); } + set { SetValue((int)UserFieldIndex.UserTitleID, value, true); } + } + /// The DateOfBirth property of the Entity User

+ ///
+ /// Mapped on table field: "User"."DateOfBirth"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable DateOfBirth + { + get { return (Nullable)GetValue((int)UserFieldIndex.DateOfBirth, false); } + set { SetValue((int)UserFieldIndex.DateOfBirth, value, true); } + } + /// The Occupation property of the Entity User

+ ///
+ /// Mapped on table field: "User"."Occupation"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 100
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String Occupation + { + get { return (System.String)GetValue((int)UserFieldIndex.Occupation, true); } + set { SetValue((int)UserFieldIndex.Occupation, value, true); } + } + /// The Location property of the Entity User

+ ///
+ /// Mapped on table field: "User"."Location"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 100
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String Location + { + get { return (System.String)GetValue((int)UserFieldIndex.Location, true); } + set { SetValue((int)UserFieldIndex.Location, value, true); } + } + /// The Website property of the Entity User

+ ///
+ /// Mapped on table field: "User"."Website"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 200
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String Website + { + get { return (System.String)GetValue((int)UserFieldIndex.Website, true); } + set { SetValue((int)UserFieldIndex.Website, value, true); } + } + /// The SignatureAsHTML property of the Entity User

+ ///
+ /// Mapped on table field: "User"."SignatureAsHTML"
+ /// Table field type characteristics (type, precision, scale, length): NVarChar, 0, 0, 1024
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.String SignatureAsHTML + { + get { return (System.String)GetValue((int)UserFieldIndex.SignatureAsHTML, true); } + set { SetValue((int)UserFieldIndex.SignatureAsHTML, value, true); } + } + /// The JoinDate property of the Entity User

+ ///
+ /// Mapped on table field: "User"."JoinDate"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable JoinDate + { + get { return (Nullable)GetValue((int)UserFieldIndex.JoinDate, false); } + set { SetValue((int)UserFieldIndex.JoinDate, value, true); } + } + /// The AmountOfPostings property of the Entity User

+ ///
+ /// Mapped on table field: "User"."AmountOfPostings"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable AmountOfPostings + { + get { return (Nullable)GetValue((int)UserFieldIndex.AmountOfPostings, false); } + set { SetValue((int)UserFieldIndex.AmountOfPostings, value, true); } + } + /// The EmailAddressIsPublic property of the Entity User

+ ///
+ /// Mapped on table field: "User"."EmailAddressIsPublic"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable EmailAddressIsPublic + { + get { return (Nullable)GetValue((int)UserFieldIndex.EmailAddressIsPublic, false); } + set { SetValue((int)UserFieldIndex.EmailAddressIsPublic, value, true); } + } + /// The LastVisitedDate property of the Entity User

+ ///
+ /// Mapped on table field: "User"."LastVisitedDate"
+ /// Table field type characteristics (type, precision, scale, length): DateTime, 23, 3, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual Nullable LastVisitedDate + { + get { return (Nullable)GetValue((int)UserFieldIndex.LastVisitedDate, false); } + set { SetValue((int)UserFieldIndex.LastVisitedDate, value, true); } + } + /// The AutoSubscribeToThread property of the Entity User

+ ///
+ /// Mapped on table field: "User"."AutoSubscribeToThread"
+ /// Table field type characteristics (type, precision, scale, length): Bit, 1, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.Boolean AutoSubscribeToThread + { + get { return (System.Boolean)GetValue((int)UserFieldIndex.AutoSubscribeToThread, true); } + set { SetValue((int)UserFieldIndex.AutoSubscribeToThread, value, true); } + } + /// The DefaultNumberOfMessagesPerPage property of the Entity User

+ ///
+ /// Mapped on table field: "User"."DefaultNumberOfMessagesPerPage"
+ /// Table field type characteristics (type, precision, scale, length): SmallInt, 5, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false
+ public virtual System.Int16 DefaultNumberOfMessagesPerPage + { + get { return (System.Int16)GetValue((int)UserFieldIndex.DefaultNumberOfMessagesPerPage, true); } + set { SetValue((int)UserFieldIndex.DefaultNumberOfMessagesPerPage, value, true); } + } + + /// Retrieves all related entities of type 'AuditDataCoreEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiLoggedAudits()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.AuditDataCoreCollection LoggedAudits + { + get { return GetMultiLoggedAudits(false); } + } + + /// Gets / sets the lazy loading flag for LoggedAudits. When set to true, LoggedAudits is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time LoggedAudits is accessed. You can always execute + /// a forced fetch by calling GetMultiLoggedAudits(true). + [Browsable(false)] + public bool AlwaysFetchLoggedAudits + { + get { return _alwaysFetchLoggedAudits; } + set { _alwaysFetchLoggedAudits = value; } + } + + /// Gets / Sets the lazy loading flag if the property LoggedAudits already has been fetched. Setting this property to false when LoggedAudits has been fetched + /// will clear the LoggedAudits collection well. Setting this property to true while LoggedAudits hasn't been fetched disables lazy loading for LoggedAudits + [Browsable(false)] + public bool AlreadyFetchedLoggedAudits + { + get { return _alreadyFetchedLoggedAudits;} + set + { + if(_alreadyFetchedLoggedAudits && !value && (_loggedAudits != null)) + { + _loggedAudits.Clear(); + } + _alreadyFetchedLoggedAudits = value; + } + } + /// Retrieves all related entities of type 'BookmarkEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiBookmarks()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.BookmarkCollection Bookmarks + { + get { return GetMultiBookmarks(false); } + } + + /// Gets / sets the lazy loading flag for Bookmarks. When set to true, Bookmarks is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Bookmarks is accessed. You can always execute + /// a forced fetch by calling GetMultiBookmarks(true). + [Browsable(false)] + public bool AlwaysFetchBookmarks + { + get { return _alwaysFetchBookmarks; } + set { _alwaysFetchBookmarks = value; } + } + + /// Gets / Sets the lazy loading flag if the property Bookmarks already has been fetched. Setting this property to false when Bookmarks has been fetched + /// will clear the Bookmarks collection well. Setting this property to true while Bookmarks hasn't been fetched disables lazy loading for Bookmarks + [Browsable(false)] + public bool AlreadyFetchedBookmarks + { + get { return _alreadyFetchedBookmarks;} + set + { + if(_alreadyFetchedBookmarks && !value && (_bookmarks != null)) + { + _bookmarks.Clear(); + } + _alreadyFetchedBookmarks = value; + } + } + /// Retrieves all related entities of type 'IPBanEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiIPBansSet()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.IPBanCollection IPBansSet + { + get { return GetMultiIPBansSet(false); } + } + + /// Gets / sets the lazy loading flag for IPBansSet. When set to true, IPBansSet is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time IPBansSet is accessed. You can always execute + /// a forced fetch by calling GetMultiIPBansSet(true). + [Browsable(false)] + public bool AlwaysFetchIPBansSet + { + get { return _alwaysFetchIPBansSet; } + set { _alwaysFetchIPBansSet = value; } + } + + /// Gets / Sets the lazy loading flag if the property IPBansSet already has been fetched. Setting this property to false when IPBansSet has been fetched + /// will clear the IPBansSet collection well. Setting this property to true while IPBansSet hasn't been fetched disables lazy loading for IPBansSet + [Browsable(false)] + public bool AlreadyFetchedIPBansSet + { + get { return _alreadyFetchedIPBansSet;} + set + { + if(_alreadyFetchedIPBansSet && !value && (_iPBansSet != null)) + { + _iPBansSet.Clear(); + } + _alreadyFetchedIPBansSet = value; + } + } + /// Retrieves all related entities of type 'MessageEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiPostedMessages()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.MessageCollection PostedMessages + { + get { return GetMultiPostedMessages(false); } + } + + /// Gets / sets the lazy loading flag for PostedMessages. When set to true, PostedMessages is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time PostedMessages is accessed. You can always execute + /// a forced fetch by calling GetMultiPostedMessages(true). + [Browsable(false)] + public bool AlwaysFetchPostedMessages + { + get { return _alwaysFetchPostedMessages; } + set { _alwaysFetchPostedMessages = value; } + } + + /// Gets / Sets the lazy loading flag if the property PostedMessages already has been fetched. Setting this property to false when PostedMessages has been fetched + /// will clear the PostedMessages collection well. Setting this property to true while PostedMessages hasn't been fetched disables lazy loading for PostedMessages + [Browsable(false)] + public bool AlreadyFetchedPostedMessages + { + get { return _alreadyFetchedPostedMessages;} + set + { + if(_alreadyFetchedPostedMessages && !value && (_postedMessages != null)) + { + _postedMessages.Clear(); + } + _alreadyFetchedPostedMessages = value; + } + } + /// Retrieves all related entities of type 'RoleUserEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiRoleUser()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleUserCollection RoleUser + { + get { return GetMultiRoleUser(false); } + } + + /// Gets / sets the lazy loading flag for RoleUser. When set to true, RoleUser is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time RoleUser is accessed. You can always execute + /// a forced fetch by calling GetMultiRoleUser(true). + [Browsable(false)] + public bool AlwaysFetchRoleUser + { + get { return _alwaysFetchRoleUser; } + set { _alwaysFetchRoleUser = value; } + } + + /// Gets / Sets the lazy loading flag if the property RoleUser already has been fetched. Setting this property to false when RoleUser has been fetched + /// will clear the RoleUser collection well. Setting this property to true while RoleUser hasn't been fetched disables lazy loading for RoleUser + [Browsable(false)] + public bool AlreadyFetchedRoleUser + { + get { return _alreadyFetchedRoleUser;} + set + { + if(_alreadyFetchedRoleUser && !value && (_roleUser != null)) + { + _roleUser.Clear(); + } + _alreadyFetchedRoleUser = value; + } + } + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiSupportQueueThreadsClaimed()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection SupportQueueThreadsClaimed + { + get { return GetMultiSupportQueueThreadsClaimed(false); } + } + + /// Gets / sets the lazy loading flag for SupportQueueThreadsClaimed. When set to true, SupportQueueThreadsClaimed is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SupportQueueThreadsClaimed is accessed. You can always execute + /// a forced fetch by calling GetMultiSupportQueueThreadsClaimed(true). + [Browsable(false)] + public bool AlwaysFetchSupportQueueThreadsClaimed + { + get { return _alwaysFetchSupportQueueThreadsClaimed; } + set { _alwaysFetchSupportQueueThreadsClaimed = value; } + } + + /// Gets / Sets the lazy loading flag if the property SupportQueueThreadsClaimed already has been fetched. Setting this property to false when SupportQueueThreadsClaimed has been fetched + /// will clear the SupportQueueThreadsClaimed collection well. Setting this property to true while SupportQueueThreadsClaimed hasn't been fetched disables lazy loading for SupportQueueThreadsClaimed + [Browsable(false)] + public bool AlreadyFetchedSupportQueueThreadsClaimed + { + get { return _alreadyFetchedSupportQueueThreadsClaimed;} + set + { + if(_alreadyFetchedSupportQueueThreadsClaimed && !value && (_supportQueueThreadsClaimed != null)) + { + _supportQueueThreadsClaimed.Clear(); + } + _alreadyFetchedSupportQueueThreadsClaimed = value; + } + } + /// Retrieves all related entities of type 'SupportQueueThreadEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiSupportQueueThreadsPlaced()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.SupportQueueThreadCollection SupportQueueThreadsPlaced + { + get { return GetMultiSupportQueueThreadsPlaced(false); } + } + + /// Gets / sets the lazy loading flag for SupportQueueThreadsPlaced. When set to true, SupportQueueThreadsPlaced is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time SupportQueueThreadsPlaced is accessed. You can always execute + /// a forced fetch by calling GetMultiSupportQueueThreadsPlaced(true). + [Browsable(false)] + public bool AlwaysFetchSupportQueueThreadsPlaced + { + get { return _alwaysFetchSupportQueueThreadsPlaced; } + set { _alwaysFetchSupportQueueThreadsPlaced = value; } + } + + /// Gets / Sets the lazy loading flag if the property SupportQueueThreadsPlaced already has been fetched. Setting this property to false when SupportQueueThreadsPlaced has been fetched + /// will clear the SupportQueueThreadsPlaced collection well. Setting this property to true while SupportQueueThreadsPlaced hasn't been fetched disables lazy loading for SupportQueueThreadsPlaced + [Browsable(false)] + public bool AlreadyFetchedSupportQueueThreadsPlaced + { + get { return _alreadyFetchedSupportQueueThreadsPlaced;} + set + { + if(_alreadyFetchedSupportQueueThreadsPlaced && !value && (_supportQueueThreadsPlaced != null)) + { + _supportQueueThreadsPlaced.Clear(); + } + _alreadyFetchedSupportQueueThreadsPlaced = value; + } + } + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiStartedThreads()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ThreadCollection StartedThreads + { + get { return GetMultiStartedThreads(false); } + } + + /// Gets / sets the lazy loading flag for StartedThreads. When set to true, StartedThreads is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time StartedThreads is accessed. You can always execute + /// a forced fetch by calling GetMultiStartedThreads(true). + [Browsable(false)] + public bool AlwaysFetchStartedThreads + { + get { return _alwaysFetchStartedThreads; } + set { _alwaysFetchStartedThreads = value; } + } + + /// Gets / Sets the lazy loading flag if the property StartedThreads already has been fetched. Setting this property to false when StartedThreads has been fetched + /// will clear the StartedThreads collection well. Setting this property to true while StartedThreads hasn't been fetched disables lazy loading for StartedThreads + [Browsable(false)] + public bool AlreadyFetchedStartedThreads + { + get { return _alreadyFetchedStartedThreads;} + set + { + if(_alreadyFetchedStartedThreads && !value && (_startedThreads != null)) + { + _startedThreads.Clear(); + } + _alreadyFetchedStartedThreads = value; + } + } + /// Retrieves all related entities of type 'ThreadSubscriptionEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiThreadSubscription()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ThreadSubscriptionCollection ThreadSubscription + { + get { return GetMultiThreadSubscription(false); } + } + + /// Gets / sets the lazy loading flag for ThreadSubscription. When set to true, ThreadSubscription is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ThreadSubscription is accessed. You can always execute + /// a forced fetch by calling GetMultiThreadSubscription(true). + [Browsable(false)] + public bool AlwaysFetchThreadSubscription + { + get { return _alwaysFetchThreadSubscription; } + set { _alwaysFetchThreadSubscription = value; } + } + + /// Gets / Sets the lazy loading flag if the property ThreadSubscription already has been fetched. Setting this property to false when ThreadSubscription has been fetched + /// will clear the ThreadSubscription collection well. Setting this property to true while ThreadSubscription hasn't been fetched disables lazy loading for ThreadSubscription + [Browsable(false)] + public bool AlreadyFetchedThreadSubscription + { + get { return _alreadyFetchedThreadSubscription;} + set + { + if(_alreadyFetchedThreadSubscription && !value && (_threadSubscription != null)) + { + _threadSubscription.Clear(); + } + _alreadyFetchedThreadSubscription = value; + } + } + + /// Retrieves all related entities of type 'ForumEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiStartedThreadsInForums()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ForumCollection StartedThreadsInForums + { + get { return GetMultiStartedThreadsInForums(false); } + } + + /// Gets / sets the lazy loading flag for StartedThreadsInForums. When set to true, StartedThreadsInForums is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time StartedThreadsInForums is accessed. You can always execute + /// a forced fetch by calling GetMultiStartedThreadsInForums(true). + [Browsable(false)] + public bool AlwaysFetchStartedThreadsInForums + { + get { return _alwaysFetchStartedThreadsInForums; } + set { _alwaysFetchStartedThreadsInForums = value; } + } + + /// Gets / Sets the lazy loading flag if the property StartedThreadsInForums already has been fetched. Setting this property to false when StartedThreadsInForums has been fetched + /// will clear the StartedThreadsInForums collection well. Setting this property to true while StartedThreadsInForums hasn't been fetched disables lazy loading for StartedThreadsInForums + [Browsable(false)] + public bool AlreadyFetchedStartedThreadsInForums + { + get { return _alreadyFetchedStartedThreadsInForums;} + set + { + if(_alreadyFetchedStartedThreadsInForums && !value && (_startedThreadsInForums != null)) + { + _startedThreadsInForums.Clear(); + } + _alreadyFetchedStartedThreadsInForums = value; + } + } + /// Retrieves all related entities of type 'RoleEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiRoles()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.RoleCollection Roles + { + get { return GetMultiRoles(false); } + } + + /// Gets / sets the lazy loading flag for Roles. When set to true, Roles is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Roles is accessed. You can always execute + /// a forced fetch by calling GetMultiRoles(true). + [Browsable(false)] + public bool AlwaysFetchRoles + { + get { return _alwaysFetchRoles; } + set { _alwaysFetchRoles = value; } + } + + /// Gets / Sets the lazy loading flag if the property Roles already has been fetched. Setting this property to false when Roles has been fetched + /// will clear the Roles collection well. Setting this property to true while Roles hasn't been fetched disables lazy loading for Roles + [Browsable(false)] + public bool AlreadyFetchedRoles + { + get { return _alreadyFetchedRoles;} + set + { + if(_alreadyFetchedRoles && !value && (_roles != null)) + { + _roles.Clear(); + } + _alreadyFetchedRoles = value; + } + } + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiThreadCollectionViaThreadSubscription()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ThreadCollection ThreadCollectionViaThreadSubscription + { + get { return GetMultiThreadCollectionViaThreadSubscription(false); } + } + + /// Gets / sets the lazy loading flag for ThreadCollectionViaThreadSubscription. When set to true, ThreadCollectionViaThreadSubscription is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ThreadCollectionViaThreadSubscription is accessed. You can always execute + /// a forced fetch by calling GetMultiThreadCollectionViaThreadSubscription(true). + [Browsable(false)] + public bool AlwaysFetchThreadCollectionViaThreadSubscription + { + get { return _alwaysFetchThreadCollectionViaThreadSubscription; } + set { _alwaysFetchThreadCollectionViaThreadSubscription = value; } + } + + /// Gets / Sets the lazy loading flag if the property ThreadCollectionViaThreadSubscription already has been fetched. Setting this property to false when ThreadCollectionViaThreadSubscription has been fetched + /// will clear the ThreadCollectionViaThreadSubscription collection well. Setting this property to true while ThreadCollectionViaThreadSubscription hasn't been fetched disables lazy loading for ThreadCollectionViaThreadSubscription + [Browsable(false)] + public bool AlreadyFetchedThreadCollectionViaThreadSubscription + { + get { return _alreadyFetchedThreadCollectionViaThreadSubscription;} + set + { + if(_alreadyFetchedThreadCollectionViaThreadSubscription && !value && (_threadCollectionViaThreadSubscription != null)) + { + _threadCollectionViaThreadSubscription.Clear(); + } + _alreadyFetchedThreadCollectionViaThreadSubscription = value; + } + } + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiPostedMessagesInThreads()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ThreadCollection PostedMessagesInThreads + { + get { return GetMultiPostedMessagesInThreads(false); } + } + + /// Gets / sets the lazy loading flag for PostedMessagesInThreads. When set to true, PostedMessagesInThreads is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time PostedMessagesInThreads is accessed. You can always execute + /// a forced fetch by calling GetMultiPostedMessagesInThreads(true). + [Browsable(false)] + public bool AlwaysFetchPostedMessagesInThreads + { + get { return _alwaysFetchPostedMessagesInThreads; } + set { _alwaysFetchPostedMessagesInThreads = value; } + } + + /// Gets / Sets the lazy loading flag if the property PostedMessagesInThreads already has been fetched. Setting this property to false when PostedMessagesInThreads has been fetched + /// will clear the PostedMessagesInThreads collection well. Setting this property to true while PostedMessagesInThreads hasn't been fetched disables lazy loading for PostedMessagesInThreads + [Browsable(false)] + public bool AlreadyFetchedPostedMessagesInThreads + { + get { return _alreadyFetchedPostedMessagesInThreads;} + set + { + if(_alreadyFetchedPostedMessagesInThreads && !value && (_postedMessagesInThreads != null)) + { + _postedMessagesInThreads.Clear(); + } + _alreadyFetchedPostedMessagesInThreads = value; + } + } + /// Retrieves all related entities of type 'ThreadEntity' using a relation of type 'm:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiThreadsInBookmarks()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.ThreadCollection ThreadsInBookmarks + { + get { return GetMultiThreadsInBookmarks(false); } + } + + /// Gets / sets the lazy loading flag for ThreadsInBookmarks. When set to true, ThreadsInBookmarks is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time ThreadsInBookmarks is accessed. You can always execute + /// a forced fetch by calling GetMultiThreadsInBookmarks(true). + [Browsable(false)] + public bool AlwaysFetchThreadsInBookmarks + { + get { return _alwaysFetchThreadsInBookmarks; } + set { _alwaysFetchThreadsInBookmarks = value; } + } + + /// Gets / Sets the lazy loading flag if the property ThreadsInBookmarks already has been fetched. Setting this property to false when ThreadsInBookmarks has been fetched + /// will clear the ThreadsInBookmarks collection well. Setting this property to true while ThreadsInBookmarks hasn't been fetched disables lazy loading for ThreadsInBookmarks + [Browsable(false)] + public bool AlreadyFetchedThreadsInBookmarks + { + get { return _alreadyFetchedThreadsInBookmarks;} + set + { + if(_alreadyFetchedThreadsInBookmarks && !value && (_threadsInBookmarks != null)) + { + _threadsInBookmarks.Clear(); + } + _alreadyFetchedThreadsInBookmarks = value; + } + } + + /// Gets / sets related entity of type 'UserTitleEntity'. This property is not visible in databound grids. + /// Setting this property to a new object will make the load-on-demand feature to stop fetching data from the database, until you set this + /// property to null. Setting this property to an entity will make sure that FK-PK relations are synchronized when appropriate. + /// This property is added for conveniance, however it is recommeded to use the method 'GetSingleUserTitle()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the + /// same scope. The property is marked non-browsable to make it hidden in bound controls, f.e. datagrids. + [Browsable(false)] + public virtual UserTitleEntity UserTitle + { + get { return GetSingleUserTitle(false); } + set + { + if(base.IsDeserializing) + { + SetupSyncUserTitle(value); + } + else + { + if(value==null) + { + if(_userTitle != null) + { + _userTitle.UnsetRelatedEntity(this, "Users"); + } + } + else + { + if(_userTitle!=value) + { + ((IEntity)value).SetRelatedEntity(this, "Users"); + } + } + } + } + } + + /// Gets / sets the lazy loading flag for UserTitle. When set to true, UserTitle is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time UserTitle is accessed. You can always execute + /// a forced fetch by calling GetSingleUserTitle(true). + [Browsable(false)] + public bool AlwaysFetchUserTitle + { + get { return _alwaysFetchUserTitle; } + set { _alwaysFetchUserTitle = value; } + } + + /// Gets / Sets the lazy loading flag if the property UserTitle already has been fetched. Setting this property to false when UserTitle has been fetched + /// will set UserTitle to null as well. Setting this property to true while UserTitle hasn't been fetched disables lazy loading for UserTitle + [Browsable(false)] + public bool AlreadyFetchedUserTitle + { + get { return _alreadyFetchedUserTitle;} + set + { + if(_alreadyFetchedUserTitle && !value) + { + this.UserTitle = null; + } + _alreadyFetchedUserTitle = value; + } + } + + /// Gets / sets the flag for what to do if the related entity available through the property UserTitle is not found + /// in the database. When set to true, UserTitle will return a new entity instance if the related entity is not found, otherwise + /// null be returned if the related entity is not found. Default: true. + [Browsable(false)] + public bool UserTitleReturnsNewIfNotFound + { + get { return _userTitleReturnsNewIfNotFound; } + set { _userTitleReturnsNewIfNotFound = value; } + } + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.UserEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityBaseClasses/UserTitleEntityBase.cs b/DAL/EntityBaseClasses/UserTitleEntityBase.cs new file mode 100644 index 0000000..a6f5c87 --- /dev/null +++ b/DAL/EntityBaseClasses/UserTitleEntityBase.cs @@ -0,0 +1,783 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Data; +using System.Xml.Serialization; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.CollectionClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + /// Entity base class which represents the base class for the entity 'UserTitle'.

+ /// + ///
+ [Serializable] + public abstract partial class UserTitleEntityBase : CommonEntityBase, ISerializable + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SD.HnD.DAL.CollectionClasses.UserCollection _users; + private bool _alwaysFetchUsers, _alreadyFetchedUsers; + + + + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Statics + private static Dictionary _customProperties; + private static Dictionary> _fieldsCustomProperties; + + /// All names of fields mapped onto a relation. Usable for in-memory filtering + public static class MemberNames + { + + /// Member name Users + public static readonly string Users = "Users"; + + + } + #endregion + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. + static UserTitleEntityBase() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public UserTitleEntityBase() + { + InitClassEmpty(null); + } + + + /// CTor + /// PK value for UserTitle which data should be fetched into this UserTitle object + public UserTitleEntityBase(System.Int32 userTitleID) + { + InitClassFetch(userTitleID, null, null); + } + + /// CTor + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// the PrefetchPath which defines the graph of objects to fetch as well + public UserTitleEntityBase(System.Int32 userTitleID, IPrefetchPath prefetchPathToUse) + { + InitClassFetch(userTitleID, null, prefetchPathToUse); + } + + /// CTor + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// The custom validator object for this UserTitleEntity + public UserTitleEntityBase(System.Int32 userTitleID, IValidator validator) + { + InitClassFetch(userTitleID, validator, null); + } + + + /// Protected CTor for deserialization + /// + /// + protected UserTitleEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + _users = (SD.HnD.DAL.CollectionClasses.UserCollection)info.GetValue("_users", typeof(SD.HnD.DAL.CollectionClasses.UserCollection)); + _alwaysFetchUsers = info.GetBoolean("_alwaysFetchUsers"); + _alreadyFetchedUsers = info.GetBoolean("_alreadyFetchedUsers"); + + + + base.FixupDeserialization(FieldInfoProviderSingleton.GetInstance(), PersistenceInfoProviderSingleton.GetInstance()); + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + + /// Performs the desync setup when an FK field has been changed. The entity referenced based on the FK field will be dereferenced and sync info will be removed. + /// The fieldindex. + protected override void PerformDesyncSetupFKFieldChange(int fieldIndex) + { + switch((UserTitleFieldIndex)fieldIndex) + { + default: + base.PerformDesyncSetupFKFieldChange(fieldIndex); + break; + } + } + + /// Gets the inheritance info provider instance of the project this entity instance is located in. + /// ready to use inheritance info provider instance. + protected override IInheritanceInfoProvider GetInheritanceInfoProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Will perform post-ReadXml actions + protected override void PostReadXmlFixups() + { + _alreadyFetchedUsers = (_users.Count > 0); + + + + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public override RelationCollection GetRelationsForFieldOfType(string fieldName) + { + return UserTitleEntity.GetRelationsForField(fieldName); + } + + /// Gets the relation objects which represent the relation the fieldName specified is mapped on. + /// Name of the field mapped onto the relation of which the relation objects have to be obtained. + /// RelationCollection with relation object(s) which represent the relation the field is maped on + public static RelationCollection GetRelationsForField(string fieldName) + { + RelationCollection toReturn = new RelationCollection(); + switch(fieldName) + { + + case "Users": + toReturn.Add(UserTitleEntity.Relations.UserEntityUsingUserTitleID); + break; + + + default: + + break; + } + return toReturn; + } + + + + /// ISerializable member. Does custom serialization so event handlers do not get serialized. + /// Serializes members of this entity class and uses the base class' implementation to serialize the rest. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_users", (!this.MarkedForDeletion?_users:null)); + info.AddValue("_alwaysFetchUsers", _alwaysFetchUsers); + info.AddValue("_alreadyFetchedUsers", _alreadyFetchedUsers); + + + + + // __LLBLGENPRO_USER_CODE_REGION_START GetObjectInfo + // __LLBLGENPRO_USER_CODE_REGION_END + base.GetObjectData(info, context); + } + + /// Sets the related entity property to the entity specified. If the property is a collection, it will add the entity specified to that collection. + /// Name of the property. + /// Entity to set as an related entity + /// Used by prefetch path logic. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntityProperty(string propertyName, IEntity entity) + { + switch(propertyName) + { + + case "Users": + _alreadyFetchedUsers = true; + if(entity!=null) + { + this.Users.Add((UserEntity)entity); + } + break; + + + default: + + break; + } + } + + /// Sets the internal parameter related to the fieldname passed to the instance relatedEntity. + /// Instance to set as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + [EditorBrowsable(EditorBrowsableState.Never)] + public override void SetRelatedEntity(IEntity relatedEntity, string fieldName) + { + switch(fieldName) + { + + case "Users": + _users.Add((UserEntity)relatedEntity); + break; + + default: + + break; + } + } + + /// Unsets the internal parameter related to the fieldname passed to the instance relatedEntity. Reverses the actions taken by SetRelatedEntity() + /// Instance to unset as the related entity of type entityType + /// Name of field mapped onto the relation which resolves in the instance relatedEntity + /// if set to true it will notify the manytoone side, if applicable. + [EditorBrowsable(EditorBrowsableState.Never)] + public override void UnsetRelatedEntity(IEntity relatedEntity, string fieldName, bool signalRelatedEntityManyToOne) + { + switch(fieldName) + { + + case "Users": + base.PerformRelatedEntityRemoval(_users, relatedEntity, signalRelatedEntityManyToOne); + break; + + default: + + break; + } + } + + /// Gets a collection of related entities referenced by this entity which depend on this entity (this entity is the PK side of their FK fields). These + /// entities will have to be persisted after this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependingRelatedEntities() + { + List toReturn = new List(); + + + return toReturn; + } + + /// Gets a collection of related entities referenced by this entity which this entity depends on (this entity is the FK side of their PK fields). These + /// entities will have to be persisted before this entity during a recursive save. + /// Collection with 0 or more IEntity objects, referenced by this entity + public override List GetDependentRelatedEntities() + { + List toReturn = new List(); + + + + return toReturn; + } + + /// Gets a List of all entity collections stored as member variables in this entity. The contents of the ArrayList is + /// used by the DataAccessAdapter to perform recursive saves. Only 1:n related collections are returned. + /// Collection with 0 or more IEntityCollection objects, referenced by this entity + public override List GetMemberEntityCollections() + { + List toReturn = new List(); + toReturn.Add(_users); + + return toReturn; + } + + + + + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userTitleID) + { + return FetchUsingPK(userTitleID, null, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userTitleID, IPrefetchPath prefetchPathToUse) + { + return FetchUsingPK(userTitleID, prefetchPathToUse, null, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userTitleID, IPrefetchPath prefetchPathToUse, Context contextToUse) + { + return Fetch(userTitleID, prefetchPathToUse, contextToUse, null); + } + + /// Fetches the contents of this entity from the persistent storage using the primary key. + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + public bool FetchUsingPK(System.Int32 userTitleID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + return Fetch(userTitleID, prefetchPathToUse, contextToUse, excludedIncludedFields); + } + + /// Refetches the Entity from the persistent storage. Refetch is used to re-load an Entity which is marked "Out-of-sync", due to a save action. + /// Refetching an empty Entity has no effect. + /// true if Refetch succeeded, false otherwise + public override bool Refetch() + { + return Fetch(this.UserTitleID, null, null, null); + } + + /// Returns true if the original value for the field with the fieldIndex passed in, read from the persistent storage was NULL, false otherwise. + /// Should not be used for testing if the current value is NULL, use for that. + /// Index of the field to test if that field was NULL in the persistent storage + /// true if the field with the passed in index was NULL in the persistent storage, false otherwise + public bool TestOriginalFieldValueForNull(UserTitleFieldIndex fieldIndex) + { + return base.Fields[(int)fieldIndex].IsNull; + } + + /// Returns true if the current value for the field with the fieldIndex passed in represents null/not defined, false otherwise. + /// Should not be used for testing if the original value (read from the db) is NULL + /// Index of the field to test if its currentvalue is null/undefined + /// true if the field's value isn't defined yet, false otherwise + public bool TestCurrentFieldValueForNull(UserTitleFieldIndex fieldIndex) + { + return base.CheckIfCurrentFieldValueIsNull((int)fieldIndex); + } + + + /// Gets a list of all the EntityRelation objects the type of this instance has. + /// A list of all the EntityRelation objects the type of this instance has. Hierarchy relations are excluded. + public override List GetAllRelations() + { + return new UserTitleRelations().GetAllRelations(); + } + + + /// Retrieves all related entities of type 'UserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Filled collection with all related entities of type 'UserEntity' + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsers(bool forceFetch) + { + return GetMultiUsers(forceFetch, _users.EntityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of type 'UserEntity' + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsers(bool forceFetch, IPredicateExpression filter) + { + return GetMultiUsers(forceFetch, _users.EntityFactoryToUse, filter); + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsers(bool forceFetch, IEntityFactory entityFactoryToUse) + { + return GetMultiUsers(forceFetch, entityFactoryToUse, null); + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type '1:n'. + /// if true, it will discard any changes currently in the collection and will rerun the complete query instead + /// The entity factory to use for the GetMultiManyToOne() routine. + /// Extra filter to limit the resultset. + /// Filled collection with all related entities of the type constructed by the passed in entity factory + public virtual SD.HnD.DAL.CollectionClasses.UserCollection GetMultiUsers(bool forceFetch, IEntityFactory entityFactoryToUse, IPredicateExpression filter) + { + if( ( !_alreadyFetchedUsers || forceFetch || _alwaysFetchUsers) && !base.IsSerializing && !base.IsDeserializing && !base.InDesignMode) + { + if(base.ParticipatesInTransaction) + { + if(!_users.ParticipatesInTransaction) + { + base.Transaction.Add(_users); + } + } + _users.SuppressClearInGetMulti=!forceFetch; + if(entityFactoryToUse!=null) + { + _users.EntityFactoryToUse = entityFactoryToUse; + } + _users.GetMultiManyToOne(this, filter); + _users.SuppressClearInGetMulti=false; + _alreadyFetchedUsers = true; + } + return _users; + } + + /// Sets the collection parameters for the collection for 'Users'. These settings will be taken into account + /// when the property Users is requested or GetMultiUsers is called. + /// The maximum number of items to return. When set to 0, this parameter is ignored + /// The order by specifications for the sorting of the resultset. When not specified (null), no sorting is applied. + public virtual void SetCollectionParametersUsers(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + _users.SortClauses=sortClauses; + _users.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; + } + + + + + /// Performs the insert action of a new Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool InsertEntity() + { + UserTitleDAO dao = (UserTitleDAO)CreateDAOInstance(); + return dao.AddNew(base.Fields, base.Transaction); + } + + /// Adds the internals to the active context. + protected override void AddInternalsToContext() + { + _users.ActiveContext = base.ActiveContext; + + + + + } + + + /// Performs the update action of an existing Entity to the persistent storage. + /// true if succeeded, false otherwise + protected override bool UpdateEntity() + { + UserTitleDAO dao = (UserTitleDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction); + } + + /// Performs the update action of an existing Entity to the persistent storage. + /// Predicate expression, meant for concurrency checks in an Update query + /// true if succeeded, false otherwise + protected override bool UpdateEntity(IPredicate updateRestriction) + { + UserTitleDAO dao = (UserTitleDAO)CreateDAOInstance(); + return dao.UpdateExisting(base.Fields, base.Transaction, updateRestriction); + } + + /// Initializes the class with empty data, as if it is a new Entity. + /// Validator to use. + protected virtual void InitClassEmpty(IValidator validatorToUse) + { + OnInitializing(); + base.Fields = CreateFields(); + base.IsNew=true; + base.Validator = validatorToUse; + + InitClassMembers(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Creates entity fields object for this entity. Used in constructor to setup this entity in a polymorphic scenario. + protected virtual IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(SD.HnD.DAL.EntityType.UserTitleEntity); + } + + /// Creates a new transaction object + /// The level of isolation. + /// The name. + protected override ITransaction CreateTransaction( IsolationLevel levelOfIsolation, string name ) + { + return new Transaction(levelOfIsolation, name); + } + + /// + /// Creates the ITypeDefaultValue instance used to provide default values for value types which aren't of type nullable(of T) + /// + /// + protected override ITypeDefaultValue CreateTypeDefaultValueProvider() + { + return new TypeDefaultValue(); + } + + /// + /// Gets all related data objects, stored by name. The name is the field name mapped onto the relation for that particular data element. + /// + /// Dictionary with per name the related referenced data element, which can be an entity collection or an entity or null + public override Dictionary GetRelatedData() + { + Dictionary toReturn = new Dictionary(); + + toReturn.Add("Users", _users); + + + return toReturn; + } + + + /// Initializes the the entity and fetches the data related to the entity in this entity. + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// The validator object for this UserTitleEntity + /// the PrefetchPath which defines the graph of objects to fetch as well + protected virtual void InitClassFetch(System.Int32 userTitleID, IValidator validator, IPrefetchPath prefetchPathToUse) + { + OnInitializing(); + base.Validator = validator; + InitClassMembers(); + base.Fields = CreateFields(); + bool wasSuccesful = Fetch(userTitleID, prefetchPathToUse, null, null); + base.IsNew = !wasSuccesful; + + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch + // __LLBLGENPRO_USER_CODE_REGION_END + + OnInitialized(); + } + + /// Initializes the class members + private void InitClassMembers() + { + _users = new SD.HnD.DAL.CollectionClasses.UserCollection(new UserEntityFactory()); + _users.SetContainingEntityInfo(this, "UserTitle"); + _alwaysFetchUsers = false; + _alreadyFetchedUsers = false; + + + + + PerformDependencyInjection(); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitClassMembersComplete(); + } + + #region Custom Property Hashtable Setup + /// Initializes the hashtables for the entity type and entity field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Dictionary(); + _fieldsCustomProperties = new Dictionary>(); + + Dictionary fieldHashtable = null; + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("UserTitleID", fieldHashtable); + fieldHashtable = new Dictionary(); + + _fieldsCustomProperties.Add("UserTitleDescription", fieldHashtable); + } + #endregion + + + + + /// Fetches the entity from the persistent storage. Fetch simply reads the entity into an EntityFields object. + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// the PrefetchPath which defines the graph of objects to fetch as well + /// The context to add the entity to if the fetch was succesful. + /// The list of IEntityField objects which have to be excluded or included for the fetch. + /// If null or empty, all fields are fetched (default). If an instance of ExcludeIncludeFieldsList is passed in and its ExcludeContainedFields property + /// is set to false, the fields contained in excludedIncludedFields are kept in the query, the rest of the fields in the query are excluded. + /// True if succeeded, false otherwise. + private bool Fetch(System.Int32 userTitleID, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) + { + try + { + OnFetch(); + IDao dao = this.CreateDAOInstance(); + base.Fields[(int)UserTitleFieldIndex.UserTitleID].ForcedCurrentValueWrite(userTitleID); + dao.FetchExisting(this, base.Transaction, prefetchPathToUse, contextToUse, excludedIncludedFields); + return (base.Fields.State == EntityState.Fetched); + } + finally + { + OnFetchComplete(); + } + } + + + /// Creates the DAO instance for this type + /// + protected override IDao CreateDAOInstance() + { + return DAOFactory.CreateUserTitleDAO(); + } + + /// Creates the entity factory for this type. + /// + protected override IEntityFactory CreateEntityFactory() + { + return new UserTitleEntityFactory(); + } + + #region Class Property Declarations + /// The relations object holding all relations of this entity with other entity classes. + public static UserTitleRelations Relations + { + get { return new UserTitleRelations(); } + } + + /// The custom properties for this entity type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary CustomProperties + { + get { return _customProperties;} + } + + + /// Creates a new PrefetchPathElement object which contains all the information to prefetch the related entities of type 'User' + /// for this entity. Add the object returned by this property to an existing PrefetchPath instance. + /// Ready to use IPrefetchPathElement implementation. + public static IPrefetchPathElement PrefetchPathUsers + { + get + { + return new PrefetchPathElement(new SD.HnD.DAL.CollectionClasses.UserCollection(), + (IEntityRelation)GetRelationsForField("Users")[0], (int)SD.HnD.DAL.EntityType.UserTitleEntity, (int)SD.HnD.DAL.EntityType.UserEntity, 0, null, null, null, "Users", SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany); + } + } + + + + + /// Returns the full name for this entity, which is important for the DAO to find back persistence info for this entity. + [Browsable(false), XmlIgnore] + public override string LLBLGenProEntityName + { + get { return "UserTitleEntity";} + } + + /// The custom properties for the type of this entity instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary CustomPropertiesOfType + { + get { return UserTitleEntity.CustomProperties;} + } + + /// The custom properties for the fields of this entity type. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Dictionary> FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this entity instance. The returned Hashtable contains per fieldname a hashtable of name-value pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [Browsable(false), XmlIgnore] + public override Dictionary> FieldsCustomPropertiesOfType + { + get { return UserTitleEntity.FieldsCustomProperties;} + } + + /// The UserTitleID property of the Entity UserTitle

+ ///
+ /// Mapped on table field: "UserTitle"."UserTitleID"
+ /// Table field type characteristics (type, precision, scale, length): Int, 10, 0, 0
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, true, true
+ public virtual System.Int32 UserTitleID + { + get { return (System.Int32)GetValue((int)UserTitleFieldIndex.UserTitleID, true); } + set { SetValue((int)UserTitleFieldIndex.UserTitleID, value, true); } + } + /// The UserTitleDescription property of the Entity UserTitle

+ ///
+ /// Mapped on table field: "UserTitle"."UserTitleDescription"
+ /// Table field type characteristics (type, precision, scale, length): VarChar, 0, 0, 50
+ /// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false
+ public virtual System.String UserTitleDescription + { + get { return (System.String)GetValue((int)UserTitleFieldIndex.UserTitleDescription, true); } + set { SetValue((int)UserTitleFieldIndex.UserTitleDescription, value, true); } + } + + /// Retrieves all related entities of type 'UserEntity' using a relation of type '1:n'. + /// This property is added for databinding conveniance, however it is recommeded to use the method 'GetMultiUsers()', because + /// this property is rather expensive and a method tells the user to cache the result when it has to be used more than once in the same scope. + public virtual SD.HnD.DAL.CollectionClasses.UserCollection Users + { + get { return GetMultiUsers(false); } + } + + /// Gets / sets the lazy loading flag for Users. When set to true, Users is always refetched from the + /// persistent storage. When set to false, the data is only fetched the first time Users is accessed. You can always execute + /// a forced fetch by calling GetMultiUsers(true). + [Browsable(false)] + public bool AlwaysFetchUsers + { + get { return _alwaysFetchUsers; } + set { _alwaysFetchUsers = value; } + } + + /// Gets / Sets the lazy loading flag if the property Users already has been fetched. Setting this property to false when Users has been fetched + /// will clear the Users collection well. Setting this property to true while Users hasn't been fetched disables lazy loading for Users + [Browsable(false)] + public bool AlreadyFetchedUsers + { + get { return _alreadyFetchedUsers;} + set + { + if(_alreadyFetchedUsers && !value && (_users != null)) + { + _users.Clear(); + } + _alreadyFetchedUsers = value; + } + } + + + + + + /// Gets or sets a value indicating whether this entity is a subtype + protected override bool LLBLGenProIsSubType + { + get { return false;} + } + + /// Gets the type of the hierarchy this entity is in. + [System.ComponentModel.Browsable(false), XmlIgnore] + protected override InheritanceHierarchyType LLBLGenProIsInHierarchyOfType + { + get { return InheritanceHierarchyType.None;} + } + + /// Returns the SD.HnD.DAL.EntityType enum value for this entity. + [Browsable(false), XmlIgnore] + public override int LLBLGenProEntityTypeValue + { + get { return (int)SD.HnD.DAL.EntityType.UserTitleEntity; } + } + #endregion + + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityClasses/ActionRightEntity.cs b/DAL/EntityClasses/ActionRightEntity.cs new file mode 100644 index 0000000..cf23b7c --- /dev/null +++ b/DAL/EntityClasses/ActionRightEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'ActionRight'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class ActionRightEntity : ActionRightEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public ActionRightEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for ActionRight which data should be fetched into this ActionRight object + public ActionRightEntity(System.Int32 actionRightID): + base(actionRightID) + { + } + + + /// + /// CTor + /// + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ActionRightEntity(System.Int32 actionRightID, IPrefetchPath prefetchPathToUse): + base(actionRightID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for ActionRight which data should be fetched into this ActionRight object + /// The custom validator object for this ActionRightEntity + public ActionRightEntity(System.Int32 actionRightID, IValidator validator): + base(actionRightID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected ActionRightEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/AttachmentEntity.cs b/DAL/EntityClasses/AttachmentEntity.cs new file mode 100644 index 0000000..6c4919f --- /dev/null +++ b/DAL/EntityClasses/AttachmentEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'Attachment'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class AttachmentEntity : AttachmentEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public AttachmentEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for Attachment which data should be fetched into this Attachment object + public AttachmentEntity(System.Int32 attachmentID): + base(attachmentID) + { + } + + + /// + /// CTor + /// + /// PK value for Attachment which data should be fetched into this Attachment object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AttachmentEntity(System.Int32 attachmentID, IPrefetchPath prefetchPathToUse): + base(attachmentID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for Attachment which data should be fetched into this Attachment object + /// The custom validator object for this AttachmentEntity + public AttachmentEntity(System.Int32 attachmentID, IValidator validator): + base(attachmentID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected AttachmentEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/AuditActionEntity.cs b/DAL/EntityClasses/AuditActionEntity.cs new file mode 100644 index 0000000..8121d6b --- /dev/null +++ b/DAL/EntityClasses/AuditActionEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'AuditAction'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class AuditActionEntity : AuditActionEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public AuditActionEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for AuditAction which data should be fetched into this AuditAction object + public AuditActionEntity(System.Int32 auditActionID): + base(auditActionID) + { + } + + + /// + /// CTor + /// + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AuditActionEntity(System.Int32 auditActionID, IPrefetchPath prefetchPathToUse): + base(auditActionID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for AuditAction which data should be fetched into this AuditAction object + /// The custom validator object for this AuditActionEntity + public AuditActionEntity(System.Int32 auditActionID, IValidator validator): + base(auditActionID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected AuditActionEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/AuditDataCoreEntity.cs b/DAL/EntityClasses/AuditDataCoreEntity.cs new file mode 100644 index 0000000..b295924 --- /dev/null +++ b/DAL/EntityClasses/AuditDataCoreEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'AuditDataCore'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class AuditDataCoreEntity : AuditDataCoreEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public AuditDataCoreEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + public AuditDataCoreEntity(System.Int32 auditDataID): + base(auditDataID) + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AuditDataCoreEntity(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse): + base(auditDataID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataCore which data should be fetched into this AuditDataCore object + /// The custom validator object for this AuditDataCoreEntity + public AuditDataCoreEntity(System.Int32 auditDataID, IValidator validator): + base(auditDataID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected AuditDataCoreEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/AuditDataMessageRelatedEntity.cs b/DAL/EntityClasses/AuditDataMessageRelatedEntity.cs new file mode 100644 index 0000000..c7c1567 --- /dev/null +++ b/DAL/EntityClasses/AuditDataMessageRelatedEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'AuditDataMessageRelated'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class AuditDataMessageRelatedEntity : AuditDataMessageRelatedEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public AuditDataMessageRelatedEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + public AuditDataMessageRelatedEntity(System.Int32 auditDataID): + base(auditDataID) + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AuditDataMessageRelatedEntity(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse): + base(auditDataID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataMessageRelated which data should be fetched into this AuditDataMessageRelated object + /// The custom validator object for this AuditDataMessageRelatedEntity + public AuditDataMessageRelatedEntity(System.Int32 auditDataID, IValidator validator): + base(auditDataID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected AuditDataMessageRelatedEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/AuditDataThreadRelatedEntity.cs b/DAL/EntityClasses/AuditDataThreadRelatedEntity.cs new file mode 100644 index 0000000..0ea8ba5 --- /dev/null +++ b/DAL/EntityClasses/AuditDataThreadRelatedEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'AuditDataThreadRelated'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class AuditDataThreadRelatedEntity : AuditDataThreadRelatedEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public AuditDataThreadRelatedEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + public AuditDataThreadRelatedEntity(System.Int32 auditDataID): + base(auditDataID) + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + /// the PrefetchPath which defines the graph of objects to fetch as well + public AuditDataThreadRelatedEntity(System.Int32 auditDataID, IPrefetchPath prefetchPathToUse): + base(auditDataID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for AuditDataThreadRelated which data should be fetched into this AuditDataThreadRelated object + /// The custom validator object for this AuditDataThreadRelatedEntity + public AuditDataThreadRelatedEntity(System.Int32 auditDataID, IValidator validator): + base(auditDataID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected AuditDataThreadRelatedEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/BookmarkEntity.cs b/DAL/EntityClasses/BookmarkEntity.cs new file mode 100644 index 0000000..b773b16 --- /dev/null +++ b/DAL/EntityClasses/BookmarkEntity.cs @@ -0,0 +1,105 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'Bookmark'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class BookmarkEntity : BookmarkEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public BookmarkEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + public BookmarkEntity(System.Int32 threadID, System.Int32 userID): + base(threadID, userID) + { + } + + + /// + /// CTor + /// + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// the PrefetchPath which defines the graph of objects to fetch as well + public BookmarkEntity(System.Int32 threadID, System.Int32 userID, IPrefetchPath prefetchPathToUse): + base(threadID, userID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// PK value for Bookmark which data should be fetched into this Bookmark object + /// The custom validator object for this BookmarkEntity + public BookmarkEntity(System.Int32 threadID, System.Int32 userID, IValidator validator): + base(threadID, userID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected BookmarkEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/CommonEntityBase.cs b/DAL/EntityClasses/CommonEntityBase.cs new file mode 100644 index 0000000..7a8c0a9 --- /dev/null +++ b/DAL/EntityClasses/CommonEntityBase.cs @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; +#if !CF +using System.Runtime.Serialization; +#endif + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// Common base class which is the base class for all generated entities which aren't a subtype of another entity. + [Serializable] + public abstract partial class CommonEntityBase : EntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + + // __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + /// CTor + public CommonEntityBase() + { + } + + /// Protected CTor for deserialization + /// + /// + protected CommonEntityBase(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included code + + #endregion + } +} diff --git a/DAL/EntityClasses/ForumEntity.cs b/DAL/EntityClasses/ForumEntity.cs new file mode 100644 index 0000000..ff5515c --- /dev/null +++ b/DAL/EntityClasses/ForumEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'Forum'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class ForumEntity : ForumEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public ForumEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for Forum which data should be fetched into this Forum object + public ForumEntity(System.Int32 forumID): + base(forumID) + { + } + + + /// + /// CTor + /// + /// PK value for Forum which data should be fetched into this Forum object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ForumEntity(System.Int32 forumID, IPrefetchPath prefetchPathToUse): + base(forumID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for Forum which data should be fetched into this Forum object + /// The custom validator object for this ForumEntity + public ForumEntity(System.Int32 forumID, IValidator validator): + base(forumID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected ForumEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/ForumRoleForumActionRightEntity.cs b/DAL/EntityClasses/ForumRoleForumActionRightEntity.cs new file mode 100644 index 0000000..4f452e4 --- /dev/null +++ b/DAL/EntityClasses/ForumRoleForumActionRightEntity.cs @@ -0,0 +1,108 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'ForumRoleForumActionRight'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class ForumRoleForumActionRightEntity : ForumRoleForumActionRightEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public ForumRoleForumActionRightEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + public ForumRoleForumActionRightEntity(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID): + base(forumID, roleID, actionRightID) + { + } + + + /// + /// CTor + /// + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ForumRoleForumActionRightEntity(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse): + base(forumID, roleID, actionRightID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// PK value for ForumRoleForumActionRight which data should be fetched into this ForumRoleForumActionRight object + /// The custom validator object for this ForumRoleForumActionRightEntity + public ForumRoleForumActionRightEntity(System.Int32 forumID, System.Int32 roleID, System.Int32 actionRightID, IValidator validator): + base(forumID, roleID, actionRightID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected ForumRoleForumActionRightEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/IPBanEntity.cs b/DAL/EntityClasses/IPBanEntity.cs new file mode 100644 index 0000000..d352354 --- /dev/null +++ b/DAL/EntityClasses/IPBanEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'IPBan'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class IPBanEntity : IPBanEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public IPBanEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for IPBan which data should be fetched into this IPBan object + public IPBanEntity(System.Int32 iPBanID): + base(iPBanID) + { + } + + + /// + /// CTor + /// + /// PK value for IPBan which data should be fetched into this IPBan object + /// the PrefetchPath which defines the graph of objects to fetch as well + public IPBanEntity(System.Int32 iPBanID, IPrefetchPath prefetchPathToUse): + base(iPBanID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for IPBan which data should be fetched into this IPBan object + /// The custom validator object for this IPBanEntity + public IPBanEntity(System.Int32 iPBanID, IValidator validator): + base(iPBanID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected IPBanEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/MessageEntity.cs b/DAL/EntityClasses/MessageEntity.cs new file mode 100644 index 0000000..d18b0d3 --- /dev/null +++ b/DAL/EntityClasses/MessageEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'Message'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class MessageEntity : MessageEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public MessageEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for Message which data should be fetched into this Message object + public MessageEntity(System.Int32 messageID): + base(messageID) + { + } + + + /// + /// CTor + /// + /// PK value for Message which data should be fetched into this Message object + /// the PrefetchPath which defines the graph of objects to fetch as well + public MessageEntity(System.Int32 messageID, IPrefetchPath prefetchPathToUse): + base(messageID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for Message which data should be fetched into this Message object + /// The custom validator object for this MessageEntity + public MessageEntity(System.Int32 messageID, IValidator validator): + base(messageID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected MessageEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/RoleAuditActionEntity.cs b/DAL/EntityClasses/RoleAuditActionEntity.cs new file mode 100644 index 0000000..b5bd4eb --- /dev/null +++ b/DAL/EntityClasses/RoleAuditActionEntity.cs @@ -0,0 +1,105 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'RoleAuditAction'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class RoleAuditActionEntity : RoleAuditActionEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public RoleAuditActionEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + public RoleAuditActionEntity(System.Int32 auditActionID, System.Int32 roleID): + base(auditActionID, roleID) + { + } + + + /// + /// CTor + /// + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// the PrefetchPath which defines the graph of objects to fetch as well + public RoleAuditActionEntity(System.Int32 auditActionID, System.Int32 roleID, IPrefetchPath prefetchPathToUse): + base(auditActionID, roleID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// PK value for RoleAuditAction which data should be fetched into this RoleAuditAction object + /// The custom validator object for this RoleAuditActionEntity + public RoleAuditActionEntity(System.Int32 auditActionID, System.Int32 roleID, IValidator validator): + base(auditActionID, roleID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected RoleAuditActionEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/RoleEntity.cs b/DAL/EntityClasses/RoleEntity.cs new file mode 100644 index 0000000..c7b2c32 --- /dev/null +++ b/DAL/EntityClasses/RoleEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'Role'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class RoleEntity : RoleEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public RoleEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for Role which data should be fetched into this Role object + public RoleEntity(System.Int32 roleID): + base(roleID) + { + } + + + /// + /// CTor + /// + /// PK value for Role which data should be fetched into this Role object + /// the PrefetchPath which defines the graph of objects to fetch as well + public RoleEntity(System.Int32 roleID, IPrefetchPath prefetchPathToUse): + base(roleID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for Role which data should be fetched into this Role object + /// The custom validator object for this RoleEntity + public RoleEntity(System.Int32 roleID, IValidator validator): + base(roleID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected RoleEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/RoleSystemActionRightEntity.cs b/DAL/EntityClasses/RoleSystemActionRightEntity.cs new file mode 100644 index 0000000..790e67f --- /dev/null +++ b/DAL/EntityClasses/RoleSystemActionRightEntity.cs @@ -0,0 +1,105 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'RoleSystemActionRight'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class RoleSystemActionRightEntity : RoleSystemActionRightEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public RoleSystemActionRightEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + public RoleSystemActionRightEntity(System.Int32 roleID, System.Int32 actionRightID): + base(roleID, actionRightID) + { + } + + + /// + /// CTor + /// + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// the PrefetchPath which defines the graph of objects to fetch as well + public RoleSystemActionRightEntity(System.Int32 roleID, System.Int32 actionRightID, IPrefetchPath prefetchPathToUse): + base(roleID, actionRightID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// PK value for RoleSystemActionRight which data should be fetched into this RoleSystemActionRight object + /// The custom validator object for this RoleSystemActionRightEntity + public RoleSystemActionRightEntity(System.Int32 roleID, System.Int32 actionRightID, IValidator validator): + base(roleID, actionRightID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected RoleSystemActionRightEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/RoleUserEntity.cs b/DAL/EntityClasses/RoleUserEntity.cs new file mode 100644 index 0000000..43b18a2 --- /dev/null +++ b/DAL/EntityClasses/RoleUserEntity.cs @@ -0,0 +1,105 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'RoleUser'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class RoleUserEntity : RoleUserEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public RoleUserEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + public RoleUserEntity(System.Int32 roleID, System.Int32 userID): + base(roleID, userID) + { + } + + + /// + /// CTor + /// + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// the PrefetchPath which defines the graph of objects to fetch as well + public RoleUserEntity(System.Int32 roleID, System.Int32 userID, IPrefetchPath prefetchPathToUse): + base(roleID, userID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// PK value for RoleUser which data should be fetched into this RoleUser object + /// The custom validator object for this RoleUserEntity + public RoleUserEntity(System.Int32 roleID, System.Int32 userID, IValidator validator): + base(roleID, userID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected RoleUserEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/SectionEntity.cs b/DAL/EntityClasses/SectionEntity.cs new file mode 100644 index 0000000..8c8821e --- /dev/null +++ b/DAL/EntityClasses/SectionEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'Section'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class SectionEntity : SectionEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public SectionEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for Section which data should be fetched into this Section object + public SectionEntity(System.Int32 sectionID): + base(sectionID) + { + } + + + /// + /// CTor + /// + /// PK value for Section which data should be fetched into this Section object + /// the PrefetchPath which defines the graph of objects to fetch as well + public SectionEntity(System.Int32 sectionID, IPrefetchPath prefetchPathToUse): + base(sectionID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for Section which data should be fetched into this Section object + /// The custom validator object for this SectionEntity + public SectionEntity(System.Int32 sectionID, IValidator validator): + base(sectionID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected SectionEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/SupportQueueEntity.cs b/DAL/EntityClasses/SupportQueueEntity.cs new file mode 100644 index 0000000..5c78c50 --- /dev/null +++ b/DAL/EntityClasses/SupportQueueEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'SupportQueue'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class SupportQueueEntity : SupportQueueEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public SupportQueueEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + public SupportQueueEntity(System.Int32 queueID): + base(queueID) + { + } + + + /// + /// CTor + /// + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// the PrefetchPath which defines the graph of objects to fetch as well + public SupportQueueEntity(System.Int32 queueID, IPrefetchPath prefetchPathToUse): + base(queueID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for SupportQueue which data should be fetched into this SupportQueue object + /// The custom validator object for this SupportQueueEntity + public SupportQueueEntity(System.Int32 queueID, IValidator validator): + base(queueID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected SupportQueueEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/SupportQueueThreadEntity.cs b/DAL/EntityClasses/SupportQueueThreadEntity.cs new file mode 100644 index 0000000..5db32b4 --- /dev/null +++ b/DAL/EntityClasses/SupportQueueThreadEntity.cs @@ -0,0 +1,105 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'SupportQueueThread'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class SupportQueueThreadEntity : SupportQueueThreadEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public SupportQueueThreadEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + public SupportQueueThreadEntity(System.Int32 queueID, System.Int32 threadID): + base(queueID, threadID) + { + } + + + /// + /// CTor + /// + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// the PrefetchPath which defines the graph of objects to fetch as well + public SupportQueueThreadEntity(System.Int32 queueID, System.Int32 threadID, IPrefetchPath prefetchPathToUse): + base(queueID, threadID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// PK value for SupportQueueThread which data should be fetched into this SupportQueueThread object + /// The custom validator object for this SupportQueueThreadEntity + public SupportQueueThreadEntity(System.Int32 queueID, System.Int32 threadID, IValidator validator): + base(queueID, threadID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected SupportQueueThreadEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/SystemDataEntity.cs b/DAL/EntityClasses/SystemDataEntity.cs new file mode 100644 index 0000000..344eb13 --- /dev/null +++ b/DAL/EntityClasses/SystemDataEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'SystemData'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class SystemDataEntity : SystemDataEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public SystemDataEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for SystemData which data should be fetched into this SystemData object + public SystemDataEntity(System.Int32 iD): + base(iD) + { + } + + + /// + /// CTor + /// + /// PK value for SystemData which data should be fetched into this SystemData object + /// the PrefetchPath which defines the graph of objects to fetch as well + public SystemDataEntity(System.Int32 iD, IPrefetchPath prefetchPathToUse): + base(iD, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for SystemData which data should be fetched into this SystemData object + /// The custom validator object for this SystemDataEntity + public SystemDataEntity(System.Int32 iD, IValidator validator): + base(iD, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected SystemDataEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/ThreadEntity.cs b/DAL/EntityClasses/ThreadEntity.cs new file mode 100644 index 0000000..04fe62a --- /dev/null +++ b/DAL/EntityClasses/ThreadEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'Thread'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class ThreadEntity : ThreadEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public ThreadEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for Thread which data should be fetched into this Thread object + public ThreadEntity(System.Int32 threadID): + base(threadID) + { + } + + + /// + /// CTor + /// + /// PK value for Thread which data should be fetched into this Thread object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ThreadEntity(System.Int32 threadID, IPrefetchPath prefetchPathToUse): + base(threadID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for Thread which data should be fetched into this Thread object + /// The custom validator object for this ThreadEntity + public ThreadEntity(System.Int32 threadID, IValidator validator): + base(threadID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected ThreadEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/ThreadSubscriptionEntity.cs b/DAL/EntityClasses/ThreadSubscriptionEntity.cs new file mode 100644 index 0000000..f9f5f8a --- /dev/null +++ b/DAL/EntityClasses/ThreadSubscriptionEntity.cs @@ -0,0 +1,105 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'ThreadSubscription'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class ThreadSubscriptionEntity : ThreadSubscriptionEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public ThreadSubscriptionEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + public ThreadSubscriptionEntity(System.Int32 userID, System.Int32 threadID): + base(userID, threadID) + { + } + + + /// + /// CTor + /// + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// the PrefetchPath which defines the graph of objects to fetch as well + public ThreadSubscriptionEntity(System.Int32 userID, System.Int32 threadID, IPrefetchPath prefetchPathToUse): + base(userID, threadID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// PK value for ThreadSubscription which data should be fetched into this ThreadSubscription object + /// The custom validator object for this ThreadSubscriptionEntity + public ThreadSubscriptionEntity(System.Int32 userID, System.Int32 threadID, IValidator validator): + base(userID, threadID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected ThreadSubscriptionEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/UserEntity.cs b/DAL/EntityClasses/UserEntity.cs new file mode 100644 index 0000000..bf61ce4 --- /dev/null +++ b/DAL/EntityClasses/UserEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'User'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class UserEntity : UserEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public UserEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for User which data should be fetched into this User object + public UserEntity(System.Int32 userID): + base(userID) + { + } + + + /// + /// CTor + /// + /// PK value for User which data should be fetched into this User object + /// the PrefetchPath which defines the graph of objects to fetch as well + public UserEntity(System.Int32 userID, IPrefetchPath prefetchPathToUse): + base(userID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for User which data should be fetched into this User object + /// The custom validator object for this UserEntity + public UserEntity(System.Int32 userID, IValidator validator): + base(userID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected UserEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/EntityClasses/UserTitleEntity.cs b/DAL/EntityClasses/UserTitleEntity.cs new file mode 100644 index 0000000..9b7a5a3 --- /dev/null +++ b/DAL/EntityClasses/UserTitleEntity.cs @@ -0,0 +1,102 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.RelationClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.EntityClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Entity class which represents the entity 'UserTitle'.
+ /// This class is used for Business Logic or for framework extension code. + ///
+ [Serializable] + public partial class UserTitleEntity : UserTitleEntityBase + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Constructors + /// + /// CTor + /// + public UserTitleEntity():base() + { + } + + + /// + /// CTor + /// + /// PK value for UserTitle which data should be fetched into this UserTitle object + public UserTitleEntity(System.Int32 userTitleID): + base(userTitleID) + { + } + + + /// + /// CTor + /// + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// the PrefetchPath which defines the graph of objects to fetch as well + public UserTitleEntity(System.Int32 userTitleID, IPrefetchPath prefetchPathToUse): + base(userTitleID, prefetchPathToUse) + { + } + + + /// + /// CTor + /// + /// PK value for UserTitle which data should be fetched into this UserTitle object + /// The custom validator object for this UserTitleEntity + public UserTitleEntity(System.Int32 userTitleID, IValidator validator): + base(userTitleID, validator) + { + } + + + /// + /// Private CTor for deserialization + /// + /// + /// + protected UserTitleEntity(SerializationInfo info, StreamingContext context) : base(info, context) + { + + // __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor + // __LLBLGENPRO_USER_CODE_REGION_END + } + #endregion + + #region Custom Entity code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/FactoryClasses/DaoFactory.cs b/DAL/FactoryClasses/DaoFactory.cs new file mode 100644 index 0000000..67113b1 --- /dev/null +++ b/DAL/FactoryClasses/DaoFactory.cs @@ -0,0 +1,203 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; + +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.FactoryClasses +{ + /// + /// Generic factory for DAO objects. + /// + public partial class DAOFactory + { + /// + /// Private CTor, no instantiation possible. + /// + private DAOFactory() + { + } + + /// Creates a new ActionRightDAO object + /// the new DAO object ready to use for ActionRight Entities + public static ActionRightDAO CreateActionRightDAO() + { + return new ActionRightDAO(); + } + + /// Creates a new AttachmentDAO object + /// the new DAO object ready to use for Attachment Entities + public static AttachmentDAO CreateAttachmentDAO() + { + return new AttachmentDAO(); + } + + /// Creates a new AuditActionDAO object + /// the new DAO object ready to use for AuditAction Entities + public static AuditActionDAO CreateAuditActionDAO() + { + return new AuditActionDAO(); + } + + /// Creates a new AuditDataCoreDAO object + /// the new DAO object ready to use for AuditDataCore Entities + public static AuditDataCoreDAO CreateAuditDataCoreDAO() + { + return new AuditDataCoreDAO(); + } + + /// Creates a new AuditDataMessageRelatedDAO object + /// the new DAO object ready to use for AuditDataMessageRelated Entities + public static AuditDataMessageRelatedDAO CreateAuditDataMessageRelatedDAO() + { + return new AuditDataMessageRelatedDAO(); + } + + /// Creates a new AuditDataThreadRelatedDAO object + /// the new DAO object ready to use for AuditDataThreadRelated Entities + public static AuditDataThreadRelatedDAO CreateAuditDataThreadRelatedDAO() + { + return new AuditDataThreadRelatedDAO(); + } + + /// Creates a new BookmarkDAO object + /// the new DAO object ready to use for Bookmark Entities + public static BookmarkDAO CreateBookmarkDAO() + { + return new BookmarkDAO(); + } + + /// Creates a new ForumDAO object + /// the new DAO object ready to use for Forum Entities + public static ForumDAO CreateForumDAO() + { + return new ForumDAO(); + } + + /// Creates a new ForumRoleForumActionRightDAO object + /// the new DAO object ready to use for ForumRoleForumActionRight Entities + public static ForumRoleForumActionRightDAO CreateForumRoleForumActionRightDAO() + { + return new ForumRoleForumActionRightDAO(); + } + + /// Creates a new IPBanDAO object + /// the new DAO object ready to use for IPBan Entities + public static IPBanDAO CreateIPBanDAO() + { + return new IPBanDAO(); + } + + /// Creates a new MessageDAO object + /// the new DAO object ready to use for Message Entities + public static MessageDAO CreateMessageDAO() + { + return new MessageDAO(); + } + + /// Creates a new RoleDAO object + /// the new DAO object ready to use for Role Entities + public static RoleDAO CreateRoleDAO() + { + return new RoleDAO(); + } + + /// Creates a new RoleAuditActionDAO object + /// the new DAO object ready to use for RoleAuditAction Entities + public static RoleAuditActionDAO CreateRoleAuditActionDAO() + { + return new RoleAuditActionDAO(); + } + + /// Creates a new RoleSystemActionRightDAO object + /// the new DAO object ready to use for RoleSystemActionRight Entities + public static RoleSystemActionRightDAO CreateRoleSystemActionRightDAO() + { + return new RoleSystemActionRightDAO(); + } + + /// Creates a new RoleUserDAO object + /// the new DAO object ready to use for RoleUser Entities + public static RoleUserDAO CreateRoleUserDAO() + { + return new RoleUserDAO(); + } + + /// Creates a new SectionDAO object + /// the new DAO object ready to use for Section Entities + public static SectionDAO CreateSectionDAO() + { + return new SectionDAO(); + } + + /// Creates a new SupportQueueDAO object + /// the new DAO object ready to use for SupportQueue Entities + public static SupportQueueDAO CreateSupportQueueDAO() + { + return new SupportQueueDAO(); + } + + /// Creates a new SupportQueueThreadDAO object + /// the new DAO object ready to use for SupportQueueThread Entities + public static SupportQueueThreadDAO CreateSupportQueueThreadDAO() + { + return new SupportQueueThreadDAO(); + } + + /// Creates a new SystemDataDAO object + /// the new DAO object ready to use for SystemData Entities + public static SystemDataDAO CreateSystemDataDAO() + { + return new SystemDataDAO(); + } + + /// Creates a new ThreadDAO object + /// the new DAO object ready to use for Thread Entities + public static ThreadDAO CreateThreadDAO() + { + return new ThreadDAO(); + } + + /// Creates a new ThreadSubscriptionDAO object + /// the new DAO object ready to use for ThreadSubscription Entities + public static ThreadSubscriptionDAO CreateThreadSubscriptionDAO() + { + return new ThreadSubscriptionDAO(); + } + + /// Creates a new UserDAO object + /// the new DAO object ready to use for User Entities + public static UserDAO CreateUserDAO() + { + return new UserDAO(); + } + + /// Creates a new UserTitleDAO object + /// the new DAO object ready to use for UserTitle Entities + public static UserTitleDAO CreateUserTitleDAO() + { + return new UserTitleDAO(); + } + + /// Creates a new TypedListDAO object + /// The new DAO object ready to use for Typed Lists + public static TypedListDAO CreateTypedListDAO() + { + return new TypedListDAO(); + } + + #region Included Code + + #endregion + } +} diff --git a/DAL/FactoryClasses/EntityFactories.cs b/DAL/FactoryClasses/EntityFactories.cs new file mode 100644 index 0000000..a88afb3 --- /dev/null +++ b/DAL/FactoryClasses/EntityFactories.cs @@ -0,0 +1,1169 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections.Generic; +using SD.HnD.DAL.HelperClasses; + +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.RelationClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.FactoryClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// general base class for the generated factories + [Serializable] + public partial class EntityFactoryBase : EntityFactoryCore + { + private string _entityName; + private SD.HnD.DAL.EntityType _typeOfEntity; + + /// CTor + /// Name of the entity. + /// The type of entity. + public EntityFactoryBase(string entityName, SD.HnD.DAL.EntityType typeOfEntity) + { + _entityName = entityName; + _typeOfEntity = typeOfEntity; + } + + /// Creates a new entity instance using the GeneralEntityFactory in the generated code, using the passed in entitytype value + /// The entity type value of the entity to create an instance for. + /// new IEntity instance + public override IEntity CreateEntityFromEntityTypeValue(int entityTypeValue) + { + return GeneralEntityFactory.Create((SD.HnD.DAL.EntityType)entityTypeValue); + } + + /// Creates, using the generated EntityFieldsFactory, the IEntityFields object for the entity to create. + /// Empty IEntityFields object. + public override IEntityFields CreateFields() + { + return EntityFieldsFactory.CreateEntityFieldsObject(_typeOfEntity); + } + + /// Creates the relations collection to the entity to join all targets so this entity can be fetched. + /// The object alias to use for the elements in the relations. + /// null if the entity isn't in a hierarchy of type TargetPerEntity, otherwise the relations collection needed to join all targets together to fetch all subtypes of this entity and this entity itself + public override IRelationCollection CreateHierarchyRelations(string objectAlias) + { + return InheritanceInfoProviderSingleton.GetInstance().GetHierarchyRelations(_entityName, objectAlias); + } + + /// This method retrieves, using the InheritanceInfoprovider, the factory for the entity represented by the values passed in. + /// Field values read from the db, to determine which factory to return, based on the field values passed in. + /// indexes into values where per entity type their own fields start. + /// the factory for the entity which is represented by the values passed in. + public override IEntityFactory GetEntityFactory(object[] fieldValues, Dictionary entityFieldStartIndexesPerEntity) + { + IEntityFactory toReturn = (IEntityFactory)InheritanceInfoProviderSingleton.GetInstance().GetEntityFactory(_entityName, fieldValues, entityFieldStartIndexesPerEntity); + if(toReturn == null) + { + toReturn = this; + } + return toReturn; + } + + /// Creates a new entity collection for the entity of this factory. + /// ready to use new entity collection, typed. + public override IEntityCollection CreateEntityCollection() + { + return GeneralEntityCollectionFactory.Create(_typeOfEntity); + } + + /// returns the name of the entity this factory is for, e.g. "EmployeeEntity" + public override string ForEntityName + { + get { return _entityName; } + } + } + + /// Factory to create new, empty ActionRightEntity objects. + [Serializable] + public partial class ActionRightEntityFactory : EntityFactoryBase { + /// CTor + public ActionRightEntityFactory() : base("ActionRightEntity", SD.HnD.DAL.EntityType.ActionRightEntity) { } + + /// Creates a new, empty ActionRightEntity object. + /// A new, empty ActionRightEntity object. + public override IEntity Create() { + IEntity toReturn = new ActionRightEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewActionRight + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new ActionRightEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewActionRightUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty AttachmentEntity objects. + [Serializable] + public partial class AttachmentEntityFactory : EntityFactoryBase { + /// CTor + public AttachmentEntityFactory() : base("AttachmentEntity", SD.HnD.DAL.EntityType.AttachmentEntity) { } + + /// Creates a new, empty AttachmentEntity object. + /// A new, empty AttachmentEntity object. + public override IEntity Create() { + IEntity toReturn = new AttachmentEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAttachment + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new AttachmentEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAttachmentUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty AuditActionEntity objects. + [Serializable] + public partial class AuditActionEntityFactory : EntityFactoryBase { + /// CTor + public AuditActionEntityFactory() : base("AuditActionEntity", SD.HnD.DAL.EntityType.AuditActionEntity) { } + + /// Creates a new, empty AuditActionEntity object. + /// A new, empty AuditActionEntity object. + public override IEntity Create() { + IEntity toReturn = new AuditActionEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAuditAction + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new AuditActionEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAuditActionUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty AuditDataCoreEntity objects. + [Serializable] + public partial class AuditDataCoreEntityFactory : EntityFactoryBase { + /// CTor + public AuditDataCoreEntityFactory() : base("AuditDataCoreEntity", SD.HnD.DAL.EntityType.AuditDataCoreEntity) { } + + /// Creates a new, empty AuditDataCoreEntity object. + /// A new, empty AuditDataCoreEntity object. + public override IEntity Create() { + IEntity toReturn = new AuditDataCoreEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAuditDataCore + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new AuditDataCoreEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAuditDataCoreUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + /// Creates the hierarchy fields for the entity to which this factory belongs. + /// IEntityFields object with the fields of all the entities in teh hierarchy of this entity or the fields of this entity if the entity isn't in a hierarchy. + public override IEntityFields CreateHierarchyFields() + { + return new EntityFields(InheritanceInfoProviderSingleton.GetInstance().GetHierarchyFields("AuditDataCoreEntity"), InheritanceInfoProviderSingleton.GetInstance(), null); + } + #region Included Code + + #endregion + } + + /// Factory to create new, empty AuditDataMessageRelatedEntity objects. + [Serializable] + public partial class AuditDataMessageRelatedEntityFactory : EntityFactoryBase { + /// CTor + public AuditDataMessageRelatedEntityFactory() : base("AuditDataMessageRelatedEntity", SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity) { } + + /// Creates a new, empty AuditDataMessageRelatedEntity object. + /// A new, empty AuditDataMessageRelatedEntity object. + public override IEntity Create() { + IEntity toReturn = new AuditDataMessageRelatedEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAuditDataMessageRelated + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new AuditDataMessageRelatedEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAuditDataMessageRelatedUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + /// Creates the hierarchy fields for the entity to which this factory belongs. + /// IEntityFields object with the fields of all the entities in teh hierarchy of this entity or the fields of this entity if the entity isn't in a hierarchy. + public override IEntityFields CreateHierarchyFields() + { + return new EntityFields(InheritanceInfoProviderSingleton.GetInstance().GetHierarchyFields("AuditDataMessageRelatedEntity"), InheritanceInfoProviderSingleton.GetInstance(), null); + } + #region Included Code + + #endregion + } + + /// Factory to create new, empty AuditDataThreadRelatedEntity objects. + [Serializable] + public partial class AuditDataThreadRelatedEntityFactory : EntityFactoryBase { + /// CTor + public AuditDataThreadRelatedEntityFactory() : base("AuditDataThreadRelatedEntity", SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity) { } + + /// Creates a new, empty AuditDataThreadRelatedEntity object. + /// A new, empty AuditDataThreadRelatedEntity object. + public override IEntity Create() { + IEntity toReturn = new AuditDataThreadRelatedEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAuditDataThreadRelated + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new AuditDataThreadRelatedEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewAuditDataThreadRelatedUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + /// Creates the hierarchy fields for the entity to which this factory belongs. + /// IEntityFields object with the fields of all the entities in teh hierarchy of this entity or the fields of this entity if the entity isn't in a hierarchy. + public override IEntityFields CreateHierarchyFields() + { + return new EntityFields(InheritanceInfoProviderSingleton.GetInstance().GetHierarchyFields("AuditDataThreadRelatedEntity"), InheritanceInfoProviderSingleton.GetInstance(), null); + } + #region Included Code + + #endregion + } + + /// Factory to create new, empty BookmarkEntity objects. + [Serializable] + public partial class BookmarkEntityFactory : EntityFactoryBase { + /// CTor + public BookmarkEntityFactory() : base("BookmarkEntity", SD.HnD.DAL.EntityType.BookmarkEntity) { } + + /// Creates a new, empty BookmarkEntity object. + /// A new, empty BookmarkEntity object. + public override IEntity Create() { + IEntity toReturn = new BookmarkEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewBookmark + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new BookmarkEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewBookmarkUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty ForumEntity objects. + [Serializable] + public partial class ForumEntityFactory : EntityFactoryBase { + /// CTor + public ForumEntityFactory() : base("ForumEntity", SD.HnD.DAL.EntityType.ForumEntity) { } + + /// Creates a new, empty ForumEntity object. + /// A new, empty ForumEntity object. + public override IEntity Create() { + IEntity toReturn = new ForumEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewForum + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new ForumEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewForumUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty ForumRoleForumActionRightEntity objects. + [Serializable] + public partial class ForumRoleForumActionRightEntityFactory : EntityFactoryBase { + /// CTor + public ForumRoleForumActionRightEntityFactory() : base("ForumRoleForumActionRightEntity", SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity) { } + + /// Creates a new, empty ForumRoleForumActionRightEntity object. + /// A new, empty ForumRoleForumActionRightEntity object. + public override IEntity Create() { + IEntity toReturn = new ForumRoleForumActionRightEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewForumRoleForumActionRight + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new ForumRoleForumActionRightEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewForumRoleForumActionRightUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty IPBanEntity objects. + [Serializable] + public partial class IPBanEntityFactory : EntityFactoryBase { + /// CTor + public IPBanEntityFactory() : base("IPBanEntity", SD.HnD.DAL.EntityType.IPBanEntity) { } + + /// Creates a new, empty IPBanEntity object. + /// A new, empty IPBanEntity object. + public override IEntity Create() { + IEntity toReturn = new IPBanEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewIPBan + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new IPBanEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewIPBanUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty MessageEntity objects. + [Serializable] + public partial class MessageEntityFactory : EntityFactoryBase { + /// CTor + public MessageEntityFactory() : base("MessageEntity", SD.HnD.DAL.EntityType.MessageEntity) { } + + /// Creates a new, empty MessageEntity object. + /// A new, empty MessageEntity object. + public override IEntity Create() { + IEntity toReturn = new MessageEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewMessage + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new MessageEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewMessageUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty RoleEntity objects. + [Serializable] + public partial class RoleEntityFactory : EntityFactoryBase { + /// CTor + public RoleEntityFactory() : base("RoleEntity", SD.HnD.DAL.EntityType.RoleEntity) { } + + /// Creates a new, empty RoleEntity object. + /// A new, empty RoleEntity object. + public override IEntity Create() { + IEntity toReturn = new RoleEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewRole + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new RoleEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewRoleUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty RoleAuditActionEntity objects. + [Serializable] + public partial class RoleAuditActionEntityFactory : EntityFactoryBase { + /// CTor + public RoleAuditActionEntityFactory() : base("RoleAuditActionEntity", SD.HnD.DAL.EntityType.RoleAuditActionEntity) { } + + /// Creates a new, empty RoleAuditActionEntity object. + /// A new, empty RoleAuditActionEntity object. + public override IEntity Create() { + IEntity toReturn = new RoleAuditActionEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewRoleAuditAction + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new RoleAuditActionEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewRoleAuditActionUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty RoleSystemActionRightEntity objects. + [Serializable] + public partial class RoleSystemActionRightEntityFactory : EntityFactoryBase { + /// CTor + public RoleSystemActionRightEntityFactory() : base("RoleSystemActionRightEntity", SD.HnD.DAL.EntityType.RoleSystemActionRightEntity) { } + + /// Creates a new, empty RoleSystemActionRightEntity object. + /// A new, empty RoleSystemActionRightEntity object. + public override IEntity Create() { + IEntity toReturn = new RoleSystemActionRightEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewRoleSystemActionRight + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new RoleSystemActionRightEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewRoleSystemActionRightUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty RoleUserEntity objects. + [Serializable] + public partial class RoleUserEntityFactory : EntityFactoryBase { + /// CTor + public RoleUserEntityFactory() : base("RoleUserEntity", SD.HnD.DAL.EntityType.RoleUserEntity) { } + + /// Creates a new, empty RoleUserEntity object. + /// A new, empty RoleUserEntity object. + public override IEntity Create() { + IEntity toReturn = new RoleUserEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewRoleUser + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new RoleUserEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewRoleUserUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty SectionEntity objects. + [Serializable] + public partial class SectionEntityFactory : EntityFactoryBase { + /// CTor + public SectionEntityFactory() : base("SectionEntity", SD.HnD.DAL.EntityType.SectionEntity) { } + + /// Creates a new, empty SectionEntity object. + /// A new, empty SectionEntity object. + public override IEntity Create() { + IEntity toReturn = new SectionEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewSection + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new SectionEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewSectionUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty SupportQueueEntity objects. + [Serializable] + public partial class SupportQueueEntityFactory : EntityFactoryBase { + /// CTor + public SupportQueueEntityFactory() : base("SupportQueueEntity", SD.HnD.DAL.EntityType.SupportQueueEntity) { } + + /// Creates a new, empty SupportQueueEntity object. + /// A new, empty SupportQueueEntity object. + public override IEntity Create() { + IEntity toReturn = new SupportQueueEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewSupportQueue + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new SupportQueueEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewSupportQueueUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty SupportQueueThreadEntity objects. + [Serializable] + public partial class SupportQueueThreadEntityFactory : EntityFactoryBase { + /// CTor + public SupportQueueThreadEntityFactory() : base("SupportQueueThreadEntity", SD.HnD.DAL.EntityType.SupportQueueThreadEntity) { } + + /// Creates a new, empty SupportQueueThreadEntity object. + /// A new, empty SupportQueueThreadEntity object. + public override IEntity Create() { + IEntity toReturn = new SupportQueueThreadEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewSupportQueueThread + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new SupportQueueThreadEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewSupportQueueThreadUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty SystemDataEntity objects. + [Serializable] + public partial class SystemDataEntityFactory : EntityFactoryBase { + /// CTor + public SystemDataEntityFactory() : base("SystemDataEntity", SD.HnD.DAL.EntityType.SystemDataEntity) { } + + /// Creates a new, empty SystemDataEntity object. + /// A new, empty SystemDataEntity object. + public override IEntity Create() { + IEntity toReturn = new SystemDataEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewSystemData + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new SystemDataEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewSystemDataUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty ThreadEntity objects. + [Serializable] + public partial class ThreadEntityFactory : EntityFactoryBase { + /// CTor + public ThreadEntityFactory() : base("ThreadEntity", SD.HnD.DAL.EntityType.ThreadEntity) { } + + /// Creates a new, empty ThreadEntity object. + /// A new, empty ThreadEntity object. + public override IEntity Create() { + IEntity toReturn = new ThreadEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewThread + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new ThreadEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewThreadUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty ThreadSubscriptionEntity objects. + [Serializable] + public partial class ThreadSubscriptionEntityFactory : EntityFactoryBase { + /// CTor + public ThreadSubscriptionEntityFactory() : base("ThreadSubscriptionEntity", SD.HnD.DAL.EntityType.ThreadSubscriptionEntity) { } + + /// Creates a new, empty ThreadSubscriptionEntity object. + /// A new, empty ThreadSubscriptionEntity object. + public override IEntity Create() { + IEntity toReturn = new ThreadSubscriptionEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewThreadSubscription + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new ThreadSubscriptionEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewThreadSubscriptionUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty UserEntity objects. + [Serializable] + public partial class UserEntityFactory : EntityFactoryBase { + /// CTor + public UserEntityFactory() : base("UserEntity", SD.HnD.DAL.EntityType.UserEntity) { } + + /// Creates a new, empty UserEntity object. + /// A new, empty UserEntity object. + public override IEntity Create() { + IEntity toReturn = new UserEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewUser + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new UserEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewUserUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new, empty UserTitleEntity objects. + [Serializable] + public partial class UserTitleEntityFactory : EntityFactoryBase { + /// CTor + public UserTitleEntityFactory() : base("UserTitleEntity", SD.HnD.DAL.EntityType.UserTitleEntity) { } + + /// Creates a new, empty UserTitleEntity object. + /// A new, empty UserTitleEntity object. + public override IEntity Create() { + IEntity toReturn = new UserTitleEntity(); + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewUserTitle + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + /// Creates a new UserTitleEntity instance and will set the Fields object of the new IEntity instance to the passed in fields object. + /// Populated IEntityFields object for the new IEntity to create + /// Fully created and populated (due to the IEntityFields object) IEntity object + public override IEntity Create(IEntityFields fields) { + IEntity toReturn = Create(); + toReturn.Fields = fields; + + // __LLBLGENPRO_USER_CODE_REGION_START CreateNewUserTitleUsingFields + // __LLBLGENPRO_USER_CODE_REGION_END + return toReturn; + } + + #region Included Code + + #endregion + } + + /// Factory to create new entity collection objects + [Serializable] + public partial class GeneralEntityCollectionFactory + { + /// Creates a new entity collection + /// The entity type to create the collection for. + /// A new entity collection object. + public static IEntityCollection Create(SD.HnD.DAL.EntityType typeToUse) + { + switch(typeToUse) + { + case SD.HnD.DAL.EntityType.ActionRightEntity: + return new ActionRightCollection(); + case SD.HnD.DAL.EntityType.AttachmentEntity: + return new AttachmentCollection(); + case SD.HnD.DAL.EntityType.AuditActionEntity: + return new AuditActionCollection(); + case SD.HnD.DAL.EntityType.AuditDataCoreEntity: + return new AuditDataCoreCollection(); + case SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity: + return new AuditDataMessageRelatedCollection(); + case SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity: + return new AuditDataThreadRelatedCollection(); + case SD.HnD.DAL.EntityType.BookmarkEntity: + return new BookmarkCollection(); + case SD.HnD.DAL.EntityType.ForumEntity: + return new ForumCollection(); + case SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity: + return new ForumRoleForumActionRightCollection(); + case SD.HnD.DAL.EntityType.IPBanEntity: + return new IPBanCollection(); + case SD.HnD.DAL.EntityType.MessageEntity: + return new MessageCollection(); + case SD.HnD.DAL.EntityType.RoleEntity: + return new RoleCollection(); + case SD.HnD.DAL.EntityType.RoleAuditActionEntity: + return new RoleAuditActionCollection(); + case SD.HnD.DAL.EntityType.RoleSystemActionRightEntity: + return new RoleSystemActionRightCollection(); + case SD.HnD.DAL.EntityType.RoleUserEntity: + return new RoleUserCollection(); + case SD.HnD.DAL.EntityType.SectionEntity: + return new SectionCollection(); + case SD.HnD.DAL.EntityType.SupportQueueEntity: + return new SupportQueueCollection(); + case SD.HnD.DAL.EntityType.SupportQueueThreadEntity: + return new SupportQueueThreadCollection(); + case SD.HnD.DAL.EntityType.SystemDataEntity: + return new SystemDataCollection(); + case SD.HnD.DAL.EntityType.ThreadEntity: + return new ThreadCollection(); + case SD.HnD.DAL.EntityType.ThreadSubscriptionEntity: + return new ThreadSubscriptionCollection(); + case SD.HnD.DAL.EntityType.UserEntity: + return new UserCollection(); + case SD.HnD.DAL.EntityType.UserTitleEntity: + return new UserTitleCollection(); + default: + return null; + } + } + } + + /// Factory to create new, empty Entity objects based on the entity type specified. Uses entity specific factory objects + [Serializable] + public partial class GeneralEntityFactory + { + /// Creates a new, empty Entity object of the type specified + /// The entity type to create. + /// A new, empty Entity object. + public static IEntity Create(SD.HnD.DAL.EntityType entityTypeToCreate) + { + IEntityFactory factoryToUse = null; + switch(entityTypeToCreate) + { + case SD.HnD.DAL.EntityType.ActionRightEntity: + factoryToUse = new ActionRightEntityFactory(); + break; + case SD.HnD.DAL.EntityType.AttachmentEntity: + factoryToUse = new AttachmentEntityFactory(); + break; + case SD.HnD.DAL.EntityType.AuditActionEntity: + factoryToUse = new AuditActionEntityFactory(); + break; + case SD.HnD.DAL.EntityType.AuditDataCoreEntity: + factoryToUse = new AuditDataCoreEntityFactory(); + break; + case SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity: + factoryToUse = new AuditDataMessageRelatedEntityFactory(); + break; + case SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity: + factoryToUse = new AuditDataThreadRelatedEntityFactory(); + break; + case SD.HnD.DAL.EntityType.BookmarkEntity: + factoryToUse = new BookmarkEntityFactory(); + break; + case SD.HnD.DAL.EntityType.ForumEntity: + factoryToUse = new ForumEntityFactory(); + break; + case SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity: + factoryToUse = new ForumRoleForumActionRightEntityFactory(); + break; + case SD.HnD.DAL.EntityType.IPBanEntity: + factoryToUse = new IPBanEntityFactory(); + break; + case SD.HnD.DAL.EntityType.MessageEntity: + factoryToUse = new MessageEntityFactory(); + break; + case SD.HnD.DAL.EntityType.RoleEntity: + factoryToUse = new RoleEntityFactory(); + break; + case SD.HnD.DAL.EntityType.RoleAuditActionEntity: + factoryToUse = new RoleAuditActionEntityFactory(); + break; + case SD.HnD.DAL.EntityType.RoleSystemActionRightEntity: + factoryToUse = new RoleSystemActionRightEntityFactory(); + break; + case SD.HnD.DAL.EntityType.RoleUserEntity: + factoryToUse = new RoleUserEntityFactory(); + break; + case SD.HnD.DAL.EntityType.SectionEntity: + factoryToUse = new SectionEntityFactory(); + break; + case SD.HnD.DAL.EntityType.SupportQueueEntity: + factoryToUse = new SupportQueueEntityFactory(); + break; + case SD.HnD.DAL.EntityType.SupportQueueThreadEntity: + factoryToUse = new SupportQueueThreadEntityFactory(); + break; + case SD.HnD.DAL.EntityType.SystemDataEntity: + factoryToUse = new SystemDataEntityFactory(); + break; + case SD.HnD.DAL.EntityType.ThreadEntity: + factoryToUse = new ThreadEntityFactory(); + break; + case SD.HnD.DAL.EntityType.ThreadSubscriptionEntity: + factoryToUse = new ThreadSubscriptionEntityFactory(); + break; + case SD.HnD.DAL.EntityType.UserEntity: + factoryToUse = new UserEntityFactory(); + break; + case SD.HnD.DAL.EntityType.UserTitleEntity: + factoryToUse = new UserTitleEntityFactory(); + break; + } + IEntity toReturn = null; + if(factoryToUse != null) + { + toReturn = factoryToUse.Create(); + } + return toReturn; + } + } + + /// Class which is used to obtain the entity factory based on the .NET type of the entity. + [Serializable] + public static class EntityFactoryFactory + { +#if CF + /// Gets the factory of the entity with the SD.HnD.DAL.EntityType specified + /// The type of entity. + /// factory to use or null if not found + public static IEntityFactory GetFactory(SD.HnD.DAL.EntityType typeOfEntity) + { + return GeneralEntityFactory.Create(typeOfEntity).GetEntityFactory(); + } +#else + private static Dictionary _factoryPerType = new Dictionary(); + + /// Initializes the class. + static EntityFactoryFactory() + { + Array entityTypeValues = Enum.GetValues(typeof(SD.HnD.DAL.EntityType)); + foreach(int entityTypeValue in entityTypeValues) + { + IEntity dummy = GeneralEntityFactory.Create((SD.HnD.DAL.EntityType)entityTypeValue); + _factoryPerType.Add(dummy.GetType(), dummy.GetEntityFactory()); + } + } + + /// Gets the factory of the entity with the .NET type specified + /// The type of entity. + /// factory to use or null if not found + public static IEntityFactory GetFactory(Type typeOfEntity) + { + IEntityFactory toReturn = null; + _factoryPerType.TryGetValue(typeOfEntity, out toReturn); + return toReturn; + } + + /// Gets the factory of the entity with the SD.HnD.DAL.EntityType specified + /// The type of entity. + /// factory to use or null if not found + public static IEntityFactory GetFactory(SD.HnD.DAL.EntityType typeOfEntity) + { + return GetFactory(GeneralEntityFactory.Create(typeOfEntity).GetType()); + } +#endif + } + + /// Element creator for creating project elements from somewhere else, like inside Linq providers. + public class ElementCreator : ElementCreatorBase, IElementCreator + { + /// Gets the factory of the Entity type with the SD.HnD.DAL.EntityType value passed in + /// The entity type value. + /// the entity factory of the entity type or null if not found + public IEntityFactory GetFactory(int entityTypeValue) + { + return (IEntityFactory)this.GetFactoryImpl(entityTypeValue); + } + + /// Gets the factory of the Entity type with the .NET type passed in + /// The type of entity. + /// the entity factory of the entity type or null if not found + public IEntityFactory GetFactory(Type typeOfEntity) + { + return (IEntityFactory)this.GetFactoryImpl(typeOfEntity); + } + + /// Creates a new resultset fields object with the number of field slots reserved as specified + /// The number of fields. + /// ready to use resultsetfields object + public IEntityFields CreateResultsetFields(int numberOfFields) + { + return new ResultsetFields(numberOfFields); + } + + /// Gets an instance of the TypedListDAO class to execute dynamic lists and projections. + /// ready to use typedlistDAO + public IDao GetTypedListDao() + { + return new TypedListDAO(); + } + + /// Creates a new dynamic relation instance + /// The left operand. + /// ready to use dynamic relation + public override IDynamicRelation CreateDynamicRelation(DerivedTableDefinition leftOperand) + { + return new DynamicRelation(leftOperand); + } + + /// Creates a new dynamic relation instance + /// The left operand. + /// Type of the join. If None is specified, Inner is assumed. + /// The right operand. + /// The on clause for the join. + /// ready to use dynamic relation + public override IDynamicRelation CreateDynamicRelation(DerivedTableDefinition leftOperand, JoinHint joinType, DerivedTableDefinition rightOperand, IPredicate onClause) + { + return new DynamicRelation(leftOperand, joinType, rightOperand, onClause); + } + + /// Creates a new dynamic relation instance + /// The left operand. + /// Type of the join. If None is specified, Inner is assumed. + /// Name of the entity, which is used as the right operand. + /// The alias of the right operand. If you don't want to / need to alias the right operand (only alias if you have to), specify string.Empty. + /// The on clause for the join. + /// ready to use dynamic relation + public override IDynamicRelation CreateDynamicRelation(DerivedTableDefinition leftOperand, JoinHint joinType, string rightOperandEntityName, string aliasRightOperand, IPredicate onClause) + { + return new DynamicRelation(leftOperand, joinType, (SD.HnD.DAL.EntityType)Enum.Parse(typeof(SD.HnD.DAL.EntityType), rightOperandEntityName, false), aliasRightOperand, onClause); + } + + /// Creates a new dynamic relation instance + /// Name of the entity which is used as the left operand. + /// Type of the join. If None is specified, Inner is assumed. + /// Name of the entity, which is used as the right operand. + /// The alias of the left operand. If you don't want to / need to alias the right operand (only alias if you have to), specify string.Empty. + /// The alias of the right operand. If you don't want to / need to alias the right operand (only alias if you have to), specify string.Empty. + /// The on clause for the join. + /// ready to use dynamic relation + public override IDynamicRelation CreateDynamicRelation(string leftOperandEntityName, JoinHint joinType, string rightOperandEntityName, string aliasLeftOperand, string aliasRightOperand, IPredicate onClause) + { + return new DynamicRelation((SD.HnD.DAL.EntityType)Enum.Parse(typeof(SD.HnD.DAL.EntityType), leftOperandEntityName, false), joinType, (SD.HnD.DAL.EntityType)Enum.Parse(typeof(SD.HnD.DAL.EntityType), rightOperandEntityName, false), aliasLeftOperand, aliasRightOperand, onClause); + } + + /// Obtains the inheritance info provider instance from the singleton + /// The singleton instance of the inheritance info provider + public override IInheritanceInfoProvider ObtainInheritanceInfoProviderInstance() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + + /// Implementation of the routine which gets the factory of the Entity type with the SD.HnD.DAL.EntityType value passed in + /// The entity type value. + /// the entity factory of the entity type or null if not found + protected override IEntityFactoryCore GetFactoryImpl(int entityTypeValue) + { + return EntityFactoryFactory.GetFactory((SD.HnD.DAL.EntityType)entityTypeValue); + } +#if !CF + /// Implementation of the routine which gets the factory of the Entity type with the .NET type passed in + /// The type of entity. + /// the entity factory of the entity type or null if not found + protected override IEntityFactoryCore GetFactoryImpl(Type typeOfEntity) + { + return EntityFactoryFactory.GetFactory(typeOfEntity); + } +#endif + } +} diff --git a/DAL/FactoryClasses/EntityFieldFactory.cs b/DAL/FactoryClasses/EntityFieldFactory.cs new file mode 100644 index 0000000..17e3a05 --- /dev/null +++ b/DAL/FactoryClasses/EntityFieldFactory.cs @@ -0,0 +1,250 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using SD.HnD.DAL; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.FactoryClasses +{ + /// + /// Factory class for IEntityField instances, used in IEntityFields instances. + /// + public partial class EntityFieldFactory + { + /// + /// Private CTor, no instantiation possible. + /// + private EntityFieldFactory() + { + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the ActionRightEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(ActionRightFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("ActionRightEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the AttachmentEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(AttachmentFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("AttachmentEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the AuditActionEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(AuditActionFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("AuditActionEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the AuditDataCoreEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(AuditDataCoreFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("AuditDataCoreEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the AuditDataMessageRelatedEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(AuditDataMessageRelatedFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("AuditDataMessageRelatedEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the AuditDataThreadRelatedEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(AuditDataThreadRelatedFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("AuditDataThreadRelatedEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the BookmarkEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(BookmarkFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("BookmarkEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the ForumEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(ForumFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("ForumEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the ForumRoleForumActionRightEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(ForumRoleForumActionRightFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("ForumRoleForumActionRightEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the IPBanEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(IPBanFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("IPBanEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the MessageEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(MessageFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("MessageEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the RoleEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(RoleFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("RoleEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the RoleAuditActionEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(RoleAuditActionFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("RoleAuditActionEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the RoleSystemActionRightEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(RoleSystemActionRightFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("RoleSystemActionRightEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the RoleUserEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(RoleUserFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("RoleUserEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the SectionEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(SectionFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("SectionEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the SupportQueueEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(SupportQueueFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("SupportQueueEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the SupportQueueThreadEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(SupportQueueThreadFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("SupportQueueThreadEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the SystemDataEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(SystemDataFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("SystemDataEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the ThreadEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(ThreadFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("ThreadEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the ThreadSubscriptionEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(ThreadSubscriptionFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("ThreadSubscriptionEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the UserEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(UserFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("UserEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + /// Creates a new IEntityField instance for usage in the EntityFields object for the UserTitleEntity. Which EntityField is created is specified by fieldIndex + /// The field which IEntityField instance should be created + /// The IEntityField instance for the field specified in fieldIndex + public static IEntityField Create(UserTitleFieldIndex fieldIndex) + { + IFieldInfo info = FieldInfoProviderSingleton.GetInstance().GetFieldInfo("UserTitleEntity", (int)fieldIndex); + return new EntityField(info, PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(info.ContainingObjectName, info.Name)); + } + + + /// Creates a new IEntityField instance, which represents the field objectName.fieldName + /// the name of the object the field belongs to, like CustomerEntity or OrdersTypedView + /// the name of the field to create + public static IEntityField Create(string objectName, string fieldName) + { + return new EntityField(FieldInfoProviderSingleton.GetInstance().GetFieldInfo(objectName, fieldName), PersistenceInfoProviderSingleton.GetInstance().GetFieldPersistenceInfo(objectName, fieldName)); + } + + #region Included Code + + #endregion + } +} diff --git a/DAL/FactoryClasses/EntityFieldsFactory.cs b/DAL/FactoryClasses/EntityFieldsFactory.cs new file mode 100644 index 0000000..8d9ce44 --- /dev/null +++ b/DAL/FactoryClasses/EntityFieldsFactory.cs @@ -0,0 +1,132 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using SD.HnD.DAL; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.FactoryClasses +{ + /// + /// Generates IEntityFields instances for different kind of Entities. + /// This class is generated. Do not modify. + /// + public partial class EntityFieldsFactory + { + /// + /// Private CTor, no instantiation possible. + /// + private EntityFieldsFactory() + { + } + + + /// General factory entrance method which will return an EntityFields object with the format generated by the factory specified + /// The type of entity the fields are for + /// The IEntityFields instance requested + public static IEntityFields CreateEntityFieldsObject(SD.HnD.DAL.EntityType relatedEntityType) + { + IEntityFields fieldsToReturn=null; + IInheritanceInfoProvider inheritanceProvider = InheritanceInfoProviderSingleton.GetInstance(); + IFieldInfoProvider fieldProvider = FieldInfoProviderSingleton.GetInstance(); + IPersistenceInfoProvider persistenceProvider = PersistenceInfoProviderSingleton.GetInstance(); + switch(relatedEntityType) + { + case SD.HnD.DAL.EntityType.ActionRightEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "ActionRightEntity"); + break; + case SD.HnD.DAL.EntityType.AttachmentEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "AttachmentEntity"); + break; + case SD.HnD.DAL.EntityType.AuditActionEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "AuditActionEntity"); + break; + case SD.HnD.DAL.EntityType.AuditDataCoreEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "AuditDataCoreEntity"); + break; + case SD.HnD.DAL.EntityType.AuditDataMessageRelatedEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "AuditDataMessageRelatedEntity"); + break; + case SD.HnD.DAL.EntityType.AuditDataThreadRelatedEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "AuditDataThreadRelatedEntity"); + break; + case SD.HnD.DAL.EntityType.BookmarkEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "BookmarkEntity"); + break; + case SD.HnD.DAL.EntityType.ForumEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "ForumEntity"); + break; + case SD.HnD.DAL.EntityType.ForumRoleForumActionRightEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "ForumRoleForumActionRightEntity"); + break; + case SD.HnD.DAL.EntityType.IPBanEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "IPBanEntity"); + break; + case SD.HnD.DAL.EntityType.MessageEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "MessageEntity"); + break; + case SD.HnD.DAL.EntityType.RoleEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "RoleEntity"); + break; + case SD.HnD.DAL.EntityType.RoleAuditActionEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "RoleAuditActionEntity"); + break; + case SD.HnD.DAL.EntityType.RoleSystemActionRightEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "RoleSystemActionRightEntity"); + break; + case SD.HnD.DAL.EntityType.RoleUserEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "RoleUserEntity"); + break; + case SD.HnD.DAL.EntityType.SectionEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "SectionEntity"); + break; + case SD.HnD.DAL.EntityType.SupportQueueEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "SupportQueueEntity"); + break; + case SD.HnD.DAL.EntityType.SupportQueueThreadEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "SupportQueueThreadEntity"); + break; + case SD.HnD.DAL.EntityType.SystemDataEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "SystemDataEntity"); + break; + case SD.HnD.DAL.EntityType.ThreadEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "ThreadEntity"); + break; + case SD.HnD.DAL.EntityType.ThreadSubscriptionEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "ThreadSubscriptionEntity"); + break; + case SD.HnD.DAL.EntityType.UserEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "UserEntity"); + break; + case SD.HnD.DAL.EntityType.UserTitleEntity: + fieldsToReturn = fieldProvider.GetEntityFields(inheritanceProvider, persistenceProvider, "UserTitleEntity"); + break; + } + return fieldsToReturn; + } + + /// General method which will return an array of IEntityFieldCore objects, used by the InheritanceInfoProvider. Only the fields defined in the entity are returned, no inherited fields. + /// the name of the entity to get the fields for. Example: "CustomerEntity" + /// array of IEntityFieldCore fields, defined in the entity with the name specified + internal static IEntityFieldCore[] CreateFields(string entityName) + { + IFieldInfoProvider fieldProvider = FieldInfoProviderSingleton.GetInstance(); + IPersistenceInfoProvider persistenceProvider = PersistenceInfoProviderSingleton.GetInstance(); + return fieldProvider.GetEntityFieldsArray(entityName, persistenceProvider); + } + + + + #region Included Code + + #endregion + } +} diff --git a/DAL/HelperClasses/DbUtils.cs b/DAL/HelperClasses/DbUtils.cs new file mode 100644 index 0000000..2001848 --- /dev/null +++ b/DAL/HelperClasses/DbUtils.cs @@ -0,0 +1,305 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SqlServerSpecific.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.Common; +using System.Data.SqlClient; +using System.Configuration; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + /// + /// General utility methods used for SqlServer usage by the framework. + /// + public partial class DbUtils + { + #region Public Static Members + public static string ActualConnectionString = string.Empty; + #endregion + + #region Constants + private const string connectionKeyString = "Main.ConnectionString"; + #endregion + + #region Class Member Declarations + private static int _commandTimeOut = 30; + #endregion + + /// + /// Private CTor, no instatiation possible + /// + private DbUtils() + { + } + + + /// + /// Sets the flag to signal the SqlServer DQE to generate SET ARITHABORT ON statements prior to INSERT, DELETE and UPDATE Queries. + /// Keep this flag to false in normal usage, but set it to true if you need to write into a table which is part of an indexed view. + /// It will not affect normal inserts/updates that much, leaving it on is not harmful. See Books online for details on SET ARITHABORT ON. + /// After each statement the setting is turned off if it has been turned on prior to that statement. + /// + /// Setting this flag is a global change. + public static void SetArithAbortFlag(bool value) + { + SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.ArithAbortOn = value; + } + + /// + /// Compatibility level used by the DQE. Default is SqlServer2000. To utilize SqlServer 2005 specific features, set this parameter + /// to SqlServer2005, either through a setting in the .config file of your application or by setting this parameter once in your application. + /// Compatibility level influences the query generated for paging, sequence name (@@IDENTITY/SCOPE_IDENTITY()), and usage of newsequenceid() in inserts. + /// It also influences the provider to use. This way you can switch between SqlServer server client 'SqlClient' and SqlServer CE Desktop. + /// + /// Setting this property will overrule a similar setting in the .config file. Don't set this property when queries are executed as + /// it might switch factories for ADO.NET elements which could result in undefined behavior. Set this property at startup of your application as it's + /// a global setting (affects all queries in your application using this DQE) + public static void SetSqlServerCompatibilityLevel(SqlServerCompatibilityLevel compatibilityLevel) + { + SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.CompatibilityLevel = compatibilityLevel; + } + + /// + /// Creates a new SqlConnection + /// + /// Conectionstring To use + /// A ready to use, closed, sqlconnection object + public static DbConnection CreateConnection(string connectionString) + { + DbConnection toReturn = SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.FactoryToUse.CreateConnection(); + toReturn.ConnectionString = connectionString; + return toReturn; + } + + + /// + /// Creates a new closed SqlConnection object based on the connection string read from the *.config file of the appdomain. + /// The connection string is stored in a key with the name defined in the constant connectionKeyString, mentioned above. + /// + /// A ready to use, closed, sqlconnection object + public static DbConnection CreateConnection() + { + if(ActualConnectionString==string.Empty) + { + ActualConnectionString = ConfigFileHelper.ReadConnectionStringFromConfig( connectionKeyString); + } + + return CreateConnection(ActualConnectionString); + } + + + /// + /// Determines which connection to use: the connection held by the passed in transaction (if any) or a new one (if no Transaction was passed in) + /// + /// A transaction the caller participates in. If null, the caller is not participating in a transaction + /// A ready to use connection object + public static IDbConnection DetermineConnectionToUse(ITransaction containingTransaction) + { + if((containingTransaction!=null)&&(containingTransaction.ConnectionToUse!=null)) + { + return containingTransaction.ConnectionToUse; + } + else + { + return CreateConnection(); + } + } + + + /// + /// Creates a new SqlDataAdapter. + /// + /// + public static DbDataAdapter CreateDataAdapter() + { + return SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.FactoryToUse.CreateDataAdapter(); + } + + + /// + /// Creates a new SqlServer transaction + /// + /// the connection to use + /// the isolation level to use + /// the name for the transaction + /// new SqlTransaction object. + public static IDbTransaction CreateTransaction(IDbConnection connectionToUse, IsolationLevel isolationLevelToUse, string name) + { + return connectionToUse.BeginTransaction(isolationLevelToUse); + } + + + /// + /// Calls the specified action stored procedure in the SqlServer database a newly created connection is connecting to. + /// + /// Stored procedure to call + /// array of parameters to specify + /// the transaction to use, or null if no transaction is available. + /// the amount of rows affected. This value will be -1 if the stored procedure sets ROWCOUNT to OFF or this has + /// been disabled in the catalog by other settings. + public static int CallActionStoredProcedure(string storedProcedureToCall, SqlParameter[] parameters, ITransaction transactionToUse ) + { + SqlCommand command = null; + bool connectionOpenedLocally = false; + string procName = SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.GetNewStoredProcedureName(storedProcedureToCall); + if(transactionToUse!=null) + { + command = new SqlCommand(procName, (SqlConnection)transactionToUse.ConnectionToUse); + command.Transaction = (SqlTransaction)transactionToUse.PhysicalTransaction; + } + else + { + command = new SqlCommand(procName, (SqlConnection)CreateConnection()); + } + command.CommandType = CommandType.StoredProcedure; + command.CommandTimeout = _commandTimeOut; + + int toReturn = -1; + try + { + for(int i=0;i + /// Calls the specified retrieval stored procedure in the SqlServer database a newly created connection is connecting to. Fills the + /// specified datatable. + /// + /// Stored procedure to call + /// array of parameters to specify + /// Datatable to fill by the stored procedure + /// the transaction to use, or null if no transaction is available. + /// true if succeeded, false otherwise + public static bool CallRetrievalStoredProcedure(string storedProcedureToCall, SqlParameter[] parameters, DataTable tableToFill, ITransaction transactionToUse) + { + SqlCommand command = null; + string procName = SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.GetNewStoredProcedureName(storedProcedureToCall); + if(transactionToUse!=null) + { + command = new SqlCommand(procName, (SqlConnection)transactionToUse.ConnectionToUse); + command.Transaction = (SqlTransaction)transactionToUse.PhysicalTransaction; + } + else + { + command = new SqlCommand(procName, (SqlConnection)CreateConnection()); + } + command.CommandType = CommandType.StoredProcedure; + command.CommandTimeout = _commandTimeOut; + + SqlDataAdapter adapter = new SqlDataAdapter(command); + for(int i=0;i + /// Calls the specified retrieval stored procedure in the SqlServer database a newly created connection is connecting to. Fills the + /// specified DataSet. + /// + /// Stored procedure to call + /// array of parameters to specify + /// DataSet to fill by the stored procedure + /// the transaction to use, or null if no transaction is available. + /// true if succeeded, false otherwise + public static bool CallRetrievalStoredProcedure(string storedProcedureToCall, SqlParameter[] parameters, DataSet dataSetToFill, ITransaction transactionToUse) + { + SqlCommand command = null; + string procName = SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.GetNewStoredProcedureName(storedProcedureToCall); + if(transactionToUse!=null) + { + command = new SqlCommand(procName, (SqlConnection)transactionToUse.ConnectionToUse); + command.Transaction = (SqlTransaction)transactionToUse.PhysicalTransaction; + } + else + { + command = new SqlCommand(procName, (SqlConnection)CreateConnection()); + } + command.CommandType = CommandType.StoredProcedure; + command.CommandTimeout = _commandTimeOut; + + SqlDataAdapter adapter = new SqlDataAdapter(command); + for(int i=0;i + /// Gets / sets the command time out (in seconds). This is a global setting, so every Command object created after you've set this + /// property to a value will have that value as CommandTimeOut. Default is 30 seconds which is the ADO.NET default. + /// + public static int CommandTimeOut + { + get + { + return _commandTimeOut; + } + set + { + _commandTimeOut = value; + SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.CommandTimeOut = _commandTimeOut; + } + } + #endregion + + + #region Included Code + + #endregion + } +} diff --git a/DAL/HelperClasses/DbUtilsComPlus.cs b/DAL/HelperClasses/DbUtilsComPlus.cs new file mode 100644 index 0000000..91cc3ab --- /dev/null +++ b/DAL/HelperClasses/DbUtilsComPlus.cs @@ -0,0 +1,123 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SqlServerSpecific.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +#if !CEDesktop +using System; +using System.Data; +using System.Data.Common; +using System.Data.SqlClient; +using System.Configuration; +using System.EnterpriseServices; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + /// + /// General utility class for COM+ transactions. + /// + [Transaction(TransactionOption.Required)] + public partial class DbUtilsComPlus : ServicedComponent + { + #region Public Static Members + public static string ActualConnectionString = string.Empty; + #endregion + + #region Constants + private const string connectionKeyString = "Main.ConnectionString"; + #endregion + + #region Class Member Declarations + private static int _commandTimeOut = 30; + #endregion + + /// + /// CTor + /// + public DbUtilsComPlus() + { + } + + + /// + /// Sets the flag to signal the SqlServer DQE to generate SET ARITHABORT ON statements prior to INSERT, DELETE and UPDATE Queries. + /// Keep this flag to false in normal usage, but set it to true if you need to write into a table which is part of an indexed view. + /// It will not affect normal inserts/updates that much, leaving it on is not harmful. See Books online for details on SET ARITHABORT ON. + /// After each statement the setting is turned off if it has been turned on prior to that statement. + /// + /// Setting this flag is a global change. + public static void SetArithAbortFlag(bool value) + { + SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.ArithAbortOn = value; + } + + /// + /// Sets the compatibility level used by the DQE. Default is SqlServer2000. To utilize SqlServer 2005 specific features, set this parameter + /// to SqlServer2005, either through a setting in the .config file of your application or by calling this method once in your application. + /// Compatibility level influences the query generated for paging, sequence name (@@IDENTITY/SCOPE_IDENTITY()), and usage of newsequenceid() in inserts. + /// + /// the compatibility level the DQE should be running on. Default is SqlServer 2000 and up. + /// Setting the compatibility level is a global change. Calling this method will overrule a similar setting in the .config file. + public static void SetSqlServerCompatibilityLevel(SqlServerCompatibilityLevel compatibilityLevel) + { + SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.CompatibilityLevel = compatibilityLevel; + } + + /// + /// Creates a new SqlConnection + /// + /// Conectionstring To use + /// A ready to use, closed, sqlconnection object + public SqlConnection CreateConnection(string connectionString) + { + return new SqlConnection(connectionString); + } + + /// + /// Creates a new closed SqlConnection object based on the connection string read from the *.config file of the appdomain. + /// The connection string is stored in a key with the name defined in the constant connectionKeyString, mentioned above. + /// + /// A ready to use, closed, sqlconnection object + public SqlConnection CreateConnection() + { + if(ActualConnectionString==string.Empty) + { + ActualConnectionString = ConfigFileHelper.ReadConnectionStringFromConfig( connectionKeyString); + } + + return CreateConnection(ActualConnectionString); + } + + + #region Class Property Declarations + /// + /// Gets / sets the command time out (in seconds). This is a global setting, so every Command object created after you've set this + /// property to a value will have that value as CommandTimeOut. Default is 30 seconds which is the ADO.NET default. + /// + public static int CommandTimeOut + { + get + { + return _commandTimeOut; + } + set + { + _commandTimeOut = value; + SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.CommandTimeOut = _commandTimeOut; + } + } + #endregion + + + #region Included Code + + #endregion + } +} +#endif \ No newline at end of file diff --git a/DAL/HelperClasses/FieldCreationClasses.cs b/DAL/HelperClasses/FieldCreationClasses.cs new file mode 100644 index 0000000..1306f40 --- /dev/null +++ b/DAL/HelperClasses/FieldCreationClasses.cs @@ -0,0 +1,783 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL; + +namespace SD.HnD.DAL.HelperClasses +{ + /// Field Creation Class for entity ActionRightEntity + public partial class ActionRightFields + { + /// Creates a new ActionRightEntity.ActionRightID field instance + public static EntityField ActionRightID + { + get { return (EntityField)EntityFieldFactory.Create(ActionRightFieldIndex.ActionRightID);} + } + /// Creates a new ActionRightEntity.ActionRightDescription field instance + public static EntityField ActionRightDescription + { + get { return (EntityField)EntityFieldFactory.Create(ActionRightFieldIndex.ActionRightDescription);} + } + /// Creates a new ActionRightEntity.AppliesToForum field instance + public static EntityField AppliesToForum + { + get { return (EntityField)EntityFieldFactory.Create(ActionRightFieldIndex.AppliesToForum);} + } + /// Creates a new ActionRightEntity.AppliesToSystem field instance + public static EntityField AppliesToSystem + { + get { return (EntityField)EntityFieldFactory.Create(ActionRightFieldIndex.AppliesToSystem);} + } + } + + /// Field Creation Class for entity AttachmentEntity + public partial class AttachmentFields + { + /// Creates a new AttachmentEntity.AttachmentID field instance + public static EntityField AttachmentID + { + get { return (EntityField)EntityFieldFactory.Create(AttachmentFieldIndex.AttachmentID);} + } + /// Creates a new AttachmentEntity.MessageID field instance + public static EntityField MessageID + { + get { return (EntityField)EntityFieldFactory.Create(AttachmentFieldIndex.MessageID);} + } + /// Creates a new AttachmentEntity.Filename field instance + public static EntityField Filename + { + get { return (EntityField)EntityFieldFactory.Create(AttachmentFieldIndex.Filename);} + } + /// Creates a new AttachmentEntity.Approved field instance + public static EntityField Approved + { + get { return (EntityField)EntityFieldFactory.Create(AttachmentFieldIndex.Approved);} + } + /// Creates a new AttachmentEntity.Filecontents field instance + public static EntityField Filecontents + { + get { return (EntityField)EntityFieldFactory.Create(AttachmentFieldIndex.Filecontents);} + } + /// Creates a new AttachmentEntity.Filesize field instance + public static EntityField Filesize + { + get { return (EntityField)EntityFieldFactory.Create(AttachmentFieldIndex.Filesize);} + } + /// Creates a new AttachmentEntity.AddedOn field instance + public static EntityField AddedOn + { + get { return (EntityField)EntityFieldFactory.Create(AttachmentFieldIndex.AddedOn);} + } + } + + /// Field Creation Class for entity AuditActionEntity + public partial class AuditActionFields + { + /// Creates a new AuditActionEntity.AuditActionID field instance + public static EntityField AuditActionID + { + get { return (EntityField)EntityFieldFactory.Create(AuditActionFieldIndex.AuditActionID);} + } + /// Creates a new AuditActionEntity.AuditActionDescription field instance + public static EntityField AuditActionDescription + { + get { return (EntityField)EntityFieldFactory.Create(AuditActionFieldIndex.AuditActionDescription);} + } + } + + /// Field Creation Class for entity AuditDataCoreEntity + public partial class AuditDataCoreFields + { + /// Creates a new AuditDataCoreEntity.AuditDataID field instance + public static EntityField AuditDataID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataCoreFieldIndex.AuditDataID);} + } + /// Creates a new AuditDataCoreEntity.AuditActionID field instance + public static EntityField AuditActionID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataCoreFieldIndex.AuditActionID);} + } + /// Creates a new AuditDataCoreEntity.UserID field instance + public static EntityField UserID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataCoreFieldIndex.UserID);} + } + /// Creates a new AuditDataCoreEntity.AuditedOn field instance + public static EntityField AuditedOn + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataCoreFieldIndex.AuditedOn);} + } + } + + /// Field Creation Class for entity AuditDataMessageRelatedEntity + public partial class AuditDataMessageRelatedFields + { + /// Creates a new AuditDataMessageRelatedEntity.AuditDataID_AuditDataCore field instance + public static EntityField AuditDataID_AuditDataCore + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataMessageRelatedFieldIndex.AuditDataID_AuditDataCore);} + } + /// Creates a new AuditDataMessageRelatedEntity.AuditActionID field instance + public static EntityField AuditActionID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataMessageRelatedFieldIndex.AuditActionID);} + } + /// Creates a new AuditDataMessageRelatedEntity.UserID field instance + public static EntityField UserID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataMessageRelatedFieldIndex.UserID);} + } + /// Creates a new AuditDataMessageRelatedEntity.AuditedOn field instance + public static EntityField AuditedOn + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataMessageRelatedFieldIndex.AuditedOn);} + } + /// Creates a new AuditDataMessageRelatedEntity.AuditDataID field instance + public static EntityField AuditDataID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataMessageRelatedFieldIndex.AuditDataID);} + } + /// Creates a new AuditDataMessageRelatedEntity.MessageID field instance + public static EntityField MessageID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataMessageRelatedFieldIndex.MessageID);} + } + } + + /// Field Creation Class for entity AuditDataThreadRelatedEntity + public partial class AuditDataThreadRelatedFields + { + /// Creates a new AuditDataThreadRelatedEntity.AuditDataID_AuditDataCore field instance + public static EntityField AuditDataID_AuditDataCore + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataThreadRelatedFieldIndex.AuditDataID_AuditDataCore);} + } + /// Creates a new AuditDataThreadRelatedEntity.AuditActionID field instance + public static EntityField AuditActionID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataThreadRelatedFieldIndex.AuditActionID);} + } + /// Creates a new AuditDataThreadRelatedEntity.UserID field instance + public static EntityField UserID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataThreadRelatedFieldIndex.UserID);} + } + /// Creates a new AuditDataThreadRelatedEntity.AuditedOn field instance + public static EntityField AuditedOn + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataThreadRelatedFieldIndex.AuditedOn);} + } + /// Creates a new AuditDataThreadRelatedEntity.AuditDataID field instance + public static EntityField AuditDataID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataThreadRelatedFieldIndex.AuditDataID);} + } + /// Creates a new AuditDataThreadRelatedEntity.ThreadID field instance + public static EntityField ThreadID + { + get { return (EntityField)EntityFieldFactory.Create(AuditDataThreadRelatedFieldIndex.ThreadID);} + } + } + + /// Field Creation Class for entity BookmarkEntity + public partial class BookmarkFields + { + /// Creates a new BookmarkEntity.ThreadID field instance + public static EntityField ThreadID + { + get { return (EntityField)EntityFieldFactory.Create(BookmarkFieldIndex.ThreadID);} + } + /// Creates a new BookmarkEntity.UserID field instance + public static EntityField UserID + { + get { return (EntityField)EntityFieldFactory.Create(BookmarkFieldIndex.UserID);} + } + } + + /// Field Creation Class for entity ForumEntity + public partial class ForumFields + { + /// Creates a new ForumEntity.ForumID field instance + public static EntityField ForumID + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.ForumID);} + } + /// Creates a new ForumEntity.SectionID field instance + public static EntityField SectionID + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.SectionID);} + } + /// Creates a new ForumEntity.ForumName field instance + public static EntityField ForumName + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.ForumName);} + } + /// Creates a new ForumEntity.ForumDescription field instance + public static EntityField ForumDescription + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.ForumDescription);} + } + /// Creates a new ForumEntity.ForumLastPostingDate field instance + public static EntityField ForumLastPostingDate + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.ForumLastPostingDate);} + } + /// Creates a new ForumEntity.HasRSSFeed field instance + public static EntityField HasRSSFeed + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.HasRSSFeed);} + } + /// Creates a new ForumEntity.DefaultSupportQueueID field instance + public static EntityField DefaultSupportQueueID + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.DefaultSupportQueueID);} + } + /// Creates a new ForumEntity.DefaultThreadListInterval field instance + public static EntityField DefaultThreadListInterval + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.DefaultThreadListInterval);} + } + /// Creates a new ForumEntity.OrderNo field instance + public static EntityField OrderNo + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.OrderNo);} + } + /// Creates a new ForumEntity.MaxAttachmentSize field instance + public static EntityField MaxAttachmentSize + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.MaxAttachmentSize);} + } + /// Creates a new ForumEntity.MaxNoOfAttachmentsPerMessage field instance + public static EntityField MaxNoOfAttachmentsPerMessage + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.MaxNoOfAttachmentsPerMessage);} + } + /// Creates a new ForumEntity.NewThreadWelcomeText field instance + public static EntityField NewThreadWelcomeText + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.NewThreadWelcomeText);} + } + /// Creates a new ForumEntity.NewThreadWelcomeTextAsHTML field instance + public static EntityField NewThreadWelcomeTextAsHTML + { + get { return (EntityField)EntityFieldFactory.Create(ForumFieldIndex.NewThreadWelcomeTextAsHTML);} + } + } + + /// Field Creation Class for entity ForumRoleForumActionRightEntity + public partial class ForumRoleForumActionRightFields + { + /// Creates a new ForumRoleForumActionRightEntity.ForumID field instance + public static EntityField ForumID + { + get { return (EntityField)EntityFieldFactory.Create(ForumRoleForumActionRightFieldIndex.ForumID);} + } + /// Creates a new ForumRoleForumActionRightEntity.RoleID field instance + public static EntityField RoleID + { + get { return (EntityField)EntityFieldFactory.Create(ForumRoleForumActionRightFieldIndex.RoleID);} + } + /// Creates a new ForumRoleForumActionRightEntity.ActionRightID field instance + public static EntityField ActionRightID + { + get { return (EntityField)EntityFieldFactory.Create(ForumRoleForumActionRightFieldIndex.ActionRightID);} + } + } + + /// Field Creation Class for entity IPBanEntity + public partial class IPBanFields + { + /// Creates a new IPBanEntity.IPBanID field instance + public static EntityField IPBanID + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.IPBanID);} + } + /// Creates a new IPBanEntity.IPSegment1 field instance + public static EntityField IPSegment1 + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.IPSegment1);} + } + /// Creates a new IPBanEntity.IPSegment2 field instance + public static EntityField IPSegment2 + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.IPSegment2);} + } + /// Creates a new IPBanEntity.IPSegment3 field instance + public static EntityField IPSegment3 + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.IPSegment3);} + } + /// Creates a new IPBanEntity.IPSegment4 field instance + public static EntityField IPSegment4 + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.IPSegment4);} + } + /// Creates a new IPBanEntity.Range field instance + public static EntityField Range + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.Range);} + } + /// Creates a new IPBanEntity.IPBanSetByUserID field instance + public static EntityField IPBanSetByUserID + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.IPBanSetByUserID);} + } + /// Creates a new IPBanEntity.IPBanSetOn field instance + public static EntityField IPBanSetOn + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.IPBanSetOn);} + } + /// Creates a new IPBanEntity.Reason field instance + public static EntityField Reason + { + get { return (EntityField)EntityFieldFactory.Create(IPBanFieldIndex.Reason);} + } + } + + /// Field Creation Class for entity MessageEntity + public partial class MessageFields + { + /// Creates a new MessageEntity.MessageID field instance + public static EntityField MessageID + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.MessageID);} + } + /// Creates a new MessageEntity.PostingDate field instance + public static EntityField PostingDate + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.PostingDate);} + } + /// Creates a new MessageEntity.PostedByUserID field instance + public static EntityField PostedByUserID + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.PostedByUserID);} + } + /// Creates a new MessageEntity.ThreadID field instance + public static EntityField ThreadID + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.ThreadID);} + } + /// Creates a new MessageEntity.PostedFromIP field instance + public static EntityField PostedFromIP + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.PostedFromIP);} + } + /// Creates a new MessageEntity.ChangeTrackerStamp field instance + public static EntityField ChangeTrackerStamp + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.ChangeTrackerStamp);} + } + /// Creates a new MessageEntity.MessageText field instance + public static EntityField MessageText + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.MessageText);} + } + /// Creates a new MessageEntity.MessageTextAsHTML field instance + public static EntityField MessageTextAsHTML + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.MessageTextAsHTML);} + } + /// Creates a new MessageEntity.MessageTextAsXml field instance + public static EntityField MessageTextAsXml + { + get { return (EntityField)EntityFieldFactory.Create(MessageFieldIndex.MessageTextAsXml);} + } + } + + /// Field Creation Class for entity RoleEntity + public partial class RoleFields + { + /// Creates a new RoleEntity.RoleID field instance + public static EntityField RoleID + { + get { return (EntityField)EntityFieldFactory.Create(RoleFieldIndex.RoleID);} + } + /// Creates a new RoleEntity.RoleDescription field instance + public static EntityField RoleDescription + { + get { return (EntityField)EntityFieldFactory.Create(RoleFieldIndex.RoleDescription);} + } + } + + /// Field Creation Class for entity RoleAuditActionEntity + public partial class RoleAuditActionFields + { + /// Creates a new RoleAuditActionEntity.AuditActionID field instance + public static EntityField AuditActionID + { + get { return (EntityField)EntityFieldFactory.Create(RoleAuditActionFieldIndex.AuditActionID);} + } + /// Creates a new RoleAuditActionEntity.RoleID field instance + public static EntityField RoleID + { + get { return (EntityField)EntityFieldFactory.Create(RoleAuditActionFieldIndex.RoleID);} + } + } + + /// Field Creation Class for entity RoleSystemActionRightEntity + public partial class RoleSystemActionRightFields + { + /// Creates a new RoleSystemActionRightEntity.RoleID field instance + public static EntityField RoleID + { + get { return (EntityField)EntityFieldFactory.Create(RoleSystemActionRightFieldIndex.RoleID);} + } + /// Creates a new RoleSystemActionRightEntity.ActionRightID field instance + public static EntityField ActionRightID + { + get { return (EntityField)EntityFieldFactory.Create(RoleSystemActionRightFieldIndex.ActionRightID);} + } + } + + /// Field Creation Class for entity RoleUserEntity + public partial class RoleUserFields + { + /// Creates a new RoleUserEntity.RoleID field instance + public static EntityField RoleID + { + get { return (EntityField)EntityFieldFactory.Create(RoleUserFieldIndex.RoleID);} + } + /// Creates a new RoleUserEntity.UserID field instance + public static EntityField UserID + { + get { return (EntityField)EntityFieldFactory.Create(RoleUserFieldIndex.UserID);} + } + } + + /// Field Creation Class for entity SectionEntity + public partial class SectionFields + { + /// Creates a new SectionEntity.SectionID field instance + public static EntityField SectionID + { + get { return (EntityField)EntityFieldFactory.Create(SectionFieldIndex.SectionID);} + } + /// Creates a new SectionEntity.SectionName field instance + public static EntityField SectionName + { + get { return (EntityField)EntityFieldFactory.Create(SectionFieldIndex.SectionName);} + } + /// Creates a new SectionEntity.SectionDescription field instance + public static EntityField SectionDescription + { + get { return (EntityField)EntityFieldFactory.Create(SectionFieldIndex.SectionDescription);} + } + /// Creates a new SectionEntity.OrderNo field instance + public static EntityField OrderNo + { + get { return (EntityField)EntityFieldFactory.Create(SectionFieldIndex.OrderNo);} + } + } + + /// Field Creation Class for entity SupportQueueEntity + public partial class SupportQueueFields + { + /// Creates a new SupportQueueEntity.QueueID field instance + public static EntityField QueueID + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueFieldIndex.QueueID);} + } + /// Creates a new SupportQueueEntity.QueueName field instance + public static EntityField QueueName + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueFieldIndex.QueueName);} + } + /// Creates a new SupportQueueEntity.QueueDescription field instance + public static EntityField QueueDescription + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueFieldIndex.QueueDescription);} + } + /// Creates a new SupportQueueEntity.OrderNo field instance + public static EntityField OrderNo + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueFieldIndex.OrderNo);} + } + } + + /// Field Creation Class for entity SupportQueueThreadEntity + public partial class SupportQueueThreadFields + { + /// Creates a new SupportQueueThreadEntity.QueueID field instance + public static EntityField QueueID + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueThreadFieldIndex.QueueID);} + } + /// Creates a new SupportQueueThreadEntity.ThreadID field instance + public static EntityField ThreadID + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueThreadFieldIndex.ThreadID);} + } + /// Creates a new SupportQueueThreadEntity.PlacedInQueueByUserID field instance + public static EntityField PlacedInQueueByUserID + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueThreadFieldIndex.PlacedInQueueByUserID);} + } + /// Creates a new SupportQueueThreadEntity.PlacedInQueueOn field instance + public static EntityField PlacedInQueueOn + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueThreadFieldIndex.PlacedInQueueOn);} + } + /// Creates a new SupportQueueThreadEntity.ClaimedByUserID field instance + public static EntityField ClaimedByUserID + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueThreadFieldIndex.ClaimedByUserID);} + } + /// Creates a new SupportQueueThreadEntity.ClaimedOn field instance + public static EntityField ClaimedOn + { + get { return (EntityField)EntityFieldFactory.Create(SupportQueueThreadFieldIndex.ClaimedOn);} + } + } + + /// Field Creation Class for entity SystemDataEntity + public partial class SystemDataFields + { + /// Creates a new SystemDataEntity.ID field instance + public static EntityField ID + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.ID);} + } + /// Creates a new SystemDataEntity.DefaultRoleNewUser field instance + public static EntityField DefaultRoleNewUser + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.DefaultRoleNewUser);} + } + /// Creates a new SystemDataEntity.AnonymousRole field instance + public static EntityField AnonymousRole + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.AnonymousRole);} + } + /// Creates a new SystemDataEntity.DefaultUserTitleNewUser field instance + public static EntityField DefaultUserTitleNewUser + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.DefaultUserTitleNewUser);} + } + /// Creates a new SystemDataEntity.HoursThresholdForActiveThreads field instance + public static EntityField HoursThresholdForActiveThreads + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.HoursThresholdForActiveThreads);} + } + /// Creates a new SystemDataEntity.PageSizeSearchResults field instance + public static EntityField PageSizeSearchResults + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.PageSizeSearchResults);} + } + /// Creates a new SystemDataEntity.MinNumberOfThreadsToFetch field instance + public static EntityField MinNumberOfThreadsToFetch + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.MinNumberOfThreadsToFetch);} + } + /// Creates a new SystemDataEntity.MinNumberOfNonStickyVisibleThreads field instance + public static EntityField MinNumberOfNonStickyVisibleThreads + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.MinNumberOfNonStickyVisibleThreads);} + } + /// Creates a new SystemDataEntity.SendReplyNotifications field instance + public static EntityField SendReplyNotifications + { + get { return (EntityField)EntityFieldFactory.Create(SystemDataFieldIndex.SendReplyNotifications);} + } + } + + /// Field Creation Class for entity ThreadEntity + public partial class ThreadFields + { + /// Creates a new ThreadEntity.ThreadID field instance + public static EntityField ThreadID + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.ThreadID);} + } + /// Creates a new ThreadEntity.ForumID field instance + public static EntityField ForumID + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.ForumID);} + } + /// Creates a new ThreadEntity.Subject field instance + public static EntityField Subject + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.Subject);} + } + /// Creates a new ThreadEntity.StartedByUserID field instance + public static EntityField StartedByUserID + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.StartedByUserID);} + } + /// Creates a new ThreadEntity.ThreadLastPostingDate field instance + public static EntityField ThreadLastPostingDate + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.ThreadLastPostingDate);} + } + /// Creates a new ThreadEntity.IsSticky field instance + public static EntityField IsSticky + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.IsSticky);} + } + /// Creates a new ThreadEntity.IsClosed field instance + public static EntityField IsClosed + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.IsClosed);} + } + /// Creates a new ThreadEntity.MarkedAsDone field instance + public static EntityField MarkedAsDone + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.MarkedAsDone);} + } + /// Creates a new ThreadEntity.NumberOfViews field instance + public static EntityField NumberOfViews + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.NumberOfViews);} + } + /// Creates a new ThreadEntity.Memo field instance + public static EntityField Memo + { + get { return (EntityField)EntityFieldFactory.Create(ThreadFieldIndex.Memo);} + } + } + + /// Field Creation Class for entity ThreadSubscriptionEntity + public partial class ThreadSubscriptionFields + { + /// Creates a new ThreadSubscriptionEntity.UserID field instance + public static EntityField UserID + { + get { return (EntityField)EntityFieldFactory.Create(ThreadSubscriptionFieldIndex.UserID);} + } + /// Creates a new ThreadSubscriptionEntity.ThreadID field instance + public static EntityField ThreadID + { + get { return (EntityField)EntityFieldFactory.Create(ThreadSubscriptionFieldIndex.ThreadID);} + } + } + + /// Field Creation Class for entity UserEntity + public partial class UserFields + { + /// Creates a new UserEntity.UserID field instance + public static EntityField UserID + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.UserID);} + } + /// Creates a new UserEntity.NickName field instance + public static EntityField NickName + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.NickName);} + } + /// Creates a new UserEntity.Password field instance + public static EntityField Password + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.Password);} + } + /// Creates a new UserEntity.IsBanned field instance + public static EntityField IsBanned + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.IsBanned);} + } + /// Creates a new UserEntity.IPNumber field instance + public static EntityField IPNumber + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.IPNumber);} + } + /// Creates a new UserEntity.Signature field instance + public static EntityField Signature + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.Signature);} + } + /// Creates a new UserEntity.IconURL field instance + public static EntityField IconURL + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.IconURL);} + } + /// Creates a new UserEntity.EmailAddress field instance + public static EntityField EmailAddress + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.EmailAddress);} + } + /// Creates a new UserEntity.UserTitleID field instance + public static EntityField UserTitleID + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.UserTitleID);} + } + /// Creates a new UserEntity.DateOfBirth field instance + public static EntityField DateOfBirth + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.DateOfBirth);} + } + /// Creates a new UserEntity.Occupation field instance + public static EntityField Occupation + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.Occupation);} + } + /// Creates a new UserEntity.Location field instance + public static EntityField Location + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.Location);} + } + /// Creates a new UserEntity.Website field instance + public static EntityField Website + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.Website);} + } + /// Creates a new UserEntity.SignatureAsHTML field instance + public static EntityField SignatureAsHTML + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.SignatureAsHTML);} + } + /// Creates a new UserEntity.JoinDate field instance + public static EntityField JoinDate + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.JoinDate);} + } + /// Creates a new UserEntity.AmountOfPostings field instance + public static EntityField AmountOfPostings + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.AmountOfPostings);} + } + /// Creates a new UserEntity.EmailAddressIsPublic field instance + public static EntityField EmailAddressIsPublic + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.EmailAddressIsPublic);} + } + /// Creates a new UserEntity.LastVisitedDate field instance + public static EntityField LastVisitedDate + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.LastVisitedDate);} + } + /// Creates a new UserEntity.AutoSubscribeToThread field instance + public static EntityField AutoSubscribeToThread + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.AutoSubscribeToThread);} + } + /// Creates a new UserEntity.DefaultNumberOfMessagesPerPage field instance + public static EntityField DefaultNumberOfMessagesPerPage + { + get { return (EntityField)EntityFieldFactory.Create(UserFieldIndex.DefaultNumberOfMessagesPerPage);} + } + } + + /// Field Creation Class for entity UserTitleEntity + public partial class UserTitleFields + { + /// Creates a new UserTitleEntity.UserTitleID field instance + public static EntityField UserTitleID + { + get { return (EntityField)EntityFieldFactory.Create(UserTitleFieldIndex.UserTitleID);} + } + /// Creates a new UserTitleEntity.UserTitleDescription field instance + public static EntityField UserTitleDescription + { + get { return (EntityField)EntityFieldFactory.Create(UserTitleFieldIndex.UserTitleDescription);} + } + } + + +} \ No newline at end of file diff --git a/DAL/HelperClasses/FieldInfoProvider.cs b/DAL/HelperClasses/FieldInfoProvider.cs new file mode 100644 index 0000000..194ab94 --- /dev/null +++ b/DAL/HelperClasses/FieldInfoProvider.cs @@ -0,0 +1,307 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Singleton implementation of the FieldInfoProvider. This class is the singleton wrapper through which the actual instance is retrieved. + /// + /// It uses a single instance of an internal class. The access isn't marked with locks as the FieldInfoProviderBase class is threadsafe. + internal sealed class FieldInfoProviderSingleton + { + #region Class Member Declarations + private static readonly IFieldInfoProvider _providerInstance = new FieldInfoProviderCore(); + #endregion + + /// private ctor to prevent instances of this class. + private FieldInfoProviderSingleton() + { + } + + /// Dummy static constructor to make sure threadsafe initialization is performed. + static FieldInfoProviderSingleton() + { + } + + /// Gets the singleton instance of the FieldInfoProviderCore + /// Instance of the FieldInfoProvider. + public static IFieldInfoProvider GetInstance() + { + return _providerInstance; + } + } + + /// Actual implementation of the FieldInfoProvider. Used by singleton wrapper. + internal class FieldInfoProviderCore : FieldInfoProviderBase + { + /// Initializes a new instance of the class. + internal FieldInfoProviderCore() + { + Init(); + } + + /// Method which initializes the internal datastores. + private void Init() + { + base.InitClass( (23 + 0)); + InitActionRightEntityInfos(); + InitAttachmentEntityInfos(); + InitAuditActionEntityInfos(); + InitAuditDataCoreEntityInfos(); + InitAuditDataMessageRelatedEntityInfos(); + InitAuditDataThreadRelatedEntityInfos(); + InitBookmarkEntityInfos(); + InitForumEntityInfos(); + InitForumRoleForumActionRightEntityInfos(); + InitIPBanEntityInfos(); + InitMessageEntityInfos(); + InitRoleEntityInfos(); + InitRoleAuditActionEntityInfos(); + InitRoleSystemActionRightEntityInfos(); + InitRoleUserEntityInfos(); + InitSectionEntityInfos(); + InitSupportQueueEntityInfos(); + InitSupportQueueThreadEntityInfos(); + InitSystemDataEntityInfos(); + InitThreadEntityInfos(); + InitThreadSubscriptionEntityInfos(); + InitUserEntityInfos(); + InitUserTitleEntityInfos(); + + base.ConstructElementFieldStructures(InheritanceInfoProviderSingleton.GetInstance()); + } + + /// Inits ActionRightEntity's FieldInfo objects + private void InitActionRightEntityInfos() + { + base.AddElementFieldInfo("ActionRightEntity", "ActionRightID", typeof(System.Int32), true, false, false, false, (int)ActionRightFieldIndex.ActionRightID, 0, 0, 10); + base.AddElementFieldInfo("ActionRightEntity", "ActionRightDescription", typeof(System.String), false, false, false, false, (int)ActionRightFieldIndex.ActionRightDescription, 50, 0, 0); + base.AddElementFieldInfo("ActionRightEntity", "AppliesToForum", typeof(System.Boolean), false, false, false, false, (int)ActionRightFieldIndex.AppliesToForum, 0, 0, 1); + base.AddElementFieldInfo("ActionRightEntity", "AppliesToSystem", typeof(System.Boolean), false, false, false, false, (int)ActionRightFieldIndex.AppliesToSystem, 0, 0, 1); + } + /// Inits AttachmentEntity's FieldInfo objects + private void InitAttachmentEntityInfos() + { + base.AddElementFieldInfo("AttachmentEntity", "AttachmentID", typeof(System.Int32), true, false, true, false, (int)AttachmentFieldIndex.AttachmentID, 0, 0, 10); + base.AddElementFieldInfo("AttachmentEntity", "MessageID", typeof(System.Int32), false, true, false, false, (int)AttachmentFieldIndex.MessageID, 0, 0, 10); + base.AddElementFieldInfo("AttachmentEntity", "Filename", typeof(System.String), false, false, false, true, (int)AttachmentFieldIndex.Filename, 255, 0, 0); + base.AddElementFieldInfo("AttachmentEntity", "Approved", typeof(System.Boolean), false, false, false, false, (int)AttachmentFieldIndex.Approved, 0, 0, 1); + base.AddElementFieldInfo("AttachmentEntity", "Filecontents", typeof(System.Byte[]), false, false, false, false, (int)AttachmentFieldIndex.Filecontents, 2147483647, 0, 0); + base.AddElementFieldInfo("AttachmentEntity", "Filesize", typeof(System.Int32), false, false, false, false, (int)AttachmentFieldIndex.Filesize, 0, 0, 10); + base.AddElementFieldInfo("AttachmentEntity", "AddedOn", typeof(System.DateTime), false, false, false, false, (int)AttachmentFieldIndex.AddedOn, 0, 3, 23); + } + /// Inits AuditActionEntity's FieldInfo objects + private void InitAuditActionEntityInfos() + { + base.AddElementFieldInfo("AuditActionEntity", "AuditActionID", typeof(System.Int32), true, false, false, false, (int)AuditActionFieldIndex.AuditActionID, 0, 0, 10); + base.AddElementFieldInfo("AuditActionEntity", "AuditActionDescription", typeof(System.String), false, false, false, true, (int)AuditActionFieldIndex.AuditActionDescription, 50, 0, 0); + } + /// Inits AuditDataCoreEntity's FieldInfo objects + private void InitAuditDataCoreEntityInfos() + { + base.AddElementFieldInfo("AuditDataCoreEntity", "AuditDataID", typeof(System.Int32), true, false, true, false, (int)AuditDataCoreFieldIndex.AuditDataID, 0, 0, 10); + base.AddElementFieldInfo("AuditDataCoreEntity", "AuditActionID", typeof(System.Int32), false, true, false, false, (int)AuditDataCoreFieldIndex.AuditActionID, 0, 0, 10); + base.AddElementFieldInfo("AuditDataCoreEntity", "UserID", typeof(System.Int32), false, true, false, false, (int)AuditDataCoreFieldIndex.UserID, 0, 0, 10); + base.AddElementFieldInfo("AuditDataCoreEntity", "AuditedOn", typeof(System.DateTime), false, false, false, false, (int)AuditDataCoreFieldIndex.AuditedOn, 0, 3, 23); + } + /// Inits AuditDataMessageRelatedEntity's FieldInfo objects + private void InitAuditDataMessageRelatedEntityInfos() + { + base.AddElementFieldInfo("AuditDataMessageRelatedEntity", "AuditDataID", typeof(System.Int32), true, false, false, false, (int)AuditDataMessageRelatedFieldIndex.AuditDataID, 0, 0, 10); + base.AddElementFieldInfo("AuditDataMessageRelatedEntity", "MessageID", typeof(System.Int32), false, true, false, false, (int)AuditDataMessageRelatedFieldIndex.MessageID, 0, 0, 10); + } + /// Inits AuditDataThreadRelatedEntity's FieldInfo objects + private void InitAuditDataThreadRelatedEntityInfos() + { + base.AddElementFieldInfo("AuditDataThreadRelatedEntity", "AuditDataID", typeof(System.Int32), true, false, false, false, (int)AuditDataThreadRelatedFieldIndex.AuditDataID, 0, 0, 10); + base.AddElementFieldInfo("AuditDataThreadRelatedEntity", "ThreadID", typeof(System.Int32), false, true, false, false, (int)AuditDataThreadRelatedFieldIndex.ThreadID, 0, 0, 10); + } + /// Inits BookmarkEntity's FieldInfo objects + private void InitBookmarkEntityInfos() + { + base.AddElementFieldInfo("BookmarkEntity", "ThreadID", typeof(System.Int32), true, true, false, false, (int)BookmarkFieldIndex.ThreadID, 0, 0, 10); + base.AddElementFieldInfo("BookmarkEntity", "UserID", typeof(System.Int32), true, true, false, false, (int)BookmarkFieldIndex.UserID, 0, 0, 10); + } + /// Inits ForumEntity's FieldInfo objects + private void InitForumEntityInfos() + { + base.AddElementFieldInfo("ForumEntity", "ForumID", typeof(System.Int32), true, false, true, false, (int)ForumFieldIndex.ForumID, 0, 0, 10); + base.AddElementFieldInfo("ForumEntity", "SectionID", typeof(System.Int32), false, true, false, false, (int)ForumFieldIndex.SectionID, 0, 0, 10); + base.AddElementFieldInfo("ForumEntity", "ForumName", typeof(System.String), false, false, false, false, (int)ForumFieldIndex.ForumName, 50, 0, 0); + base.AddElementFieldInfo("ForumEntity", "ForumDescription", typeof(System.String), false, false, false, false, (int)ForumFieldIndex.ForumDescription, 250, 0, 0); + base.AddElementFieldInfo("ForumEntity", "ForumLastPostingDate", typeof(Nullable), false, false, false, true, (int)ForumFieldIndex.ForumLastPostingDate, 0, 3, 23); + base.AddElementFieldInfo("ForumEntity", "HasRSSFeed", typeof(System.Boolean), false, false, false, false, (int)ForumFieldIndex.HasRSSFeed, 0, 0, 1); + base.AddElementFieldInfo("ForumEntity", "DefaultSupportQueueID", typeof(Nullable), false, true, false, true, (int)ForumFieldIndex.DefaultSupportQueueID, 0, 0, 10); + base.AddElementFieldInfo("ForumEntity", "DefaultThreadListInterval", typeof(System.Byte), false, false, false, false, (int)ForumFieldIndex.DefaultThreadListInterval, 0, 0, 3); + base.AddElementFieldInfo("ForumEntity", "OrderNo", typeof(System.Int16), false, false, false, false, (int)ForumFieldIndex.OrderNo, 0, 0, 5); + base.AddElementFieldInfo("ForumEntity", "MaxAttachmentSize", typeof(System.Int32), false, false, false, true, (int)ForumFieldIndex.MaxAttachmentSize, 0, 0, 10); + base.AddElementFieldInfo("ForumEntity", "MaxNoOfAttachmentsPerMessage", typeof(System.Int16), false, false, false, true, (int)ForumFieldIndex.MaxNoOfAttachmentsPerMessage, 0, 0, 5); + base.AddElementFieldInfo("ForumEntity", "NewThreadWelcomeText", typeof(System.String), false, false, false, true, (int)ForumFieldIndex.NewThreadWelcomeText, 1073741823, 0, 0); + base.AddElementFieldInfo("ForumEntity", "NewThreadWelcomeTextAsHTML", typeof(System.String), false, false, false, true, (int)ForumFieldIndex.NewThreadWelcomeTextAsHTML, 1073741823, 0, 0); + } + /// Inits ForumRoleForumActionRightEntity's FieldInfo objects + private void InitForumRoleForumActionRightEntityInfos() + { + base.AddElementFieldInfo("ForumRoleForumActionRightEntity", "ForumID", typeof(System.Int32), true, true, false, false, (int)ForumRoleForumActionRightFieldIndex.ForumID, 0, 0, 10); + base.AddElementFieldInfo("ForumRoleForumActionRightEntity", "RoleID", typeof(System.Int32), true, true, false, false, (int)ForumRoleForumActionRightFieldIndex.RoleID, 0, 0, 10); + base.AddElementFieldInfo("ForumRoleForumActionRightEntity", "ActionRightID", typeof(System.Int32), true, true, false, false, (int)ForumRoleForumActionRightFieldIndex.ActionRightID, 0, 0, 10); + } + /// Inits IPBanEntity's FieldInfo objects + private void InitIPBanEntityInfos() + { + base.AddElementFieldInfo("IPBanEntity", "IPBanID", typeof(System.Int32), true, false, true, false, (int)IPBanFieldIndex.IPBanID, 0, 0, 10); + base.AddElementFieldInfo("IPBanEntity", "IPSegment1", typeof(System.Byte), false, false, false, false, (int)IPBanFieldIndex.IPSegment1, 0, 0, 3); + base.AddElementFieldInfo("IPBanEntity", "IPSegment2", typeof(System.Byte), false, false, false, false, (int)IPBanFieldIndex.IPSegment2, 0, 0, 3); + base.AddElementFieldInfo("IPBanEntity", "IPSegment3", typeof(System.Byte), false, false, false, false, (int)IPBanFieldIndex.IPSegment3, 0, 0, 3); + base.AddElementFieldInfo("IPBanEntity", "IPSegment4", typeof(System.Byte), false, false, false, false, (int)IPBanFieldIndex.IPSegment4, 0, 0, 3); + base.AddElementFieldInfo("IPBanEntity", "Range", typeof(System.Byte), false, false, false, false, (int)IPBanFieldIndex.Range, 0, 0, 3); + base.AddElementFieldInfo("IPBanEntity", "IPBanSetByUserID", typeof(System.Int32), false, true, false, false, (int)IPBanFieldIndex.IPBanSetByUserID, 0, 0, 10); + base.AddElementFieldInfo("IPBanEntity", "IPBanSetOn", typeof(System.DateTime), false, false, false, false, (int)IPBanFieldIndex.IPBanSetOn, 0, 3, 23); + base.AddElementFieldInfo("IPBanEntity", "Reason", typeof(System.String), false, false, false, false, (int)IPBanFieldIndex.Reason, 1073741823, 0, 0); + } + /// Inits MessageEntity's FieldInfo objects + private void InitMessageEntityInfos() + { + base.AddElementFieldInfo("MessageEntity", "MessageID", typeof(System.Int32), true, false, true, false, (int)MessageFieldIndex.MessageID, 0, 0, 10); + base.AddElementFieldInfo("MessageEntity", "PostingDate", typeof(System.DateTime), false, false, false, false, (int)MessageFieldIndex.PostingDate, 0, 3, 23); + base.AddElementFieldInfo("MessageEntity", "PostedByUserID", typeof(System.Int32), false, true, false, false, (int)MessageFieldIndex.PostedByUserID, 0, 0, 10); + base.AddElementFieldInfo("MessageEntity", "ThreadID", typeof(System.Int32), false, true, false, false, (int)MessageFieldIndex.ThreadID, 0, 0, 10); + base.AddElementFieldInfo("MessageEntity", "PostedFromIP", typeof(System.String), false, false, false, false, (int)MessageFieldIndex.PostedFromIP, 25, 0, 0); + base.AddElementFieldInfo("MessageEntity", "ChangeTrackerStamp", typeof(System.Byte[]), false, false, true, false, (int)MessageFieldIndex.ChangeTrackerStamp, 8, 0, 0); + base.AddElementFieldInfo("MessageEntity", "MessageText", typeof(System.String), false, false, false, true, (int)MessageFieldIndex.MessageText, 1073741823, 0, 0); + base.AddElementFieldInfo("MessageEntity", "MessageTextAsHTML", typeof(System.String), false, false, false, true, (int)MessageFieldIndex.MessageTextAsHTML, 1073741823, 0, 0); + base.AddElementFieldInfo("MessageEntity", "MessageTextAsXml", typeof(System.String), false, false, false, true, (int)MessageFieldIndex.MessageTextAsXml, 1073741823, 0, 0); + } + /// Inits RoleEntity's FieldInfo objects + private void InitRoleEntityInfos() + { + base.AddElementFieldInfo("RoleEntity", "RoleID", typeof(System.Int32), true, false, true, false, (int)RoleFieldIndex.RoleID, 0, 0, 10); + base.AddElementFieldInfo("RoleEntity", "RoleDescription", typeof(System.String), false, false, false, false, (int)RoleFieldIndex.RoleDescription, 50, 0, 0); + } + /// Inits RoleAuditActionEntity's FieldInfo objects + private void InitRoleAuditActionEntityInfos() + { + base.AddElementFieldInfo("RoleAuditActionEntity", "AuditActionID", typeof(System.Int32), true, true, false, false, (int)RoleAuditActionFieldIndex.AuditActionID, 0, 0, 10); + base.AddElementFieldInfo("RoleAuditActionEntity", "RoleID", typeof(System.Int32), true, true, false, false, (int)RoleAuditActionFieldIndex.RoleID, 0, 0, 10); + } + /// Inits RoleSystemActionRightEntity's FieldInfo objects + private void InitRoleSystemActionRightEntityInfos() + { + base.AddElementFieldInfo("RoleSystemActionRightEntity", "RoleID", typeof(System.Int32), true, true, false, false, (int)RoleSystemActionRightFieldIndex.RoleID, 0, 0, 10); + base.AddElementFieldInfo("RoleSystemActionRightEntity", "ActionRightID", typeof(System.Int32), true, true, false, false, (int)RoleSystemActionRightFieldIndex.ActionRightID, 0, 0, 10); + } + /// Inits RoleUserEntity's FieldInfo objects + private void InitRoleUserEntityInfos() + { + base.AddElementFieldInfo("RoleUserEntity", "RoleID", typeof(System.Int32), true, true, false, false, (int)RoleUserFieldIndex.RoleID, 0, 0, 10); + base.AddElementFieldInfo("RoleUserEntity", "UserID", typeof(System.Int32), true, true, false, false, (int)RoleUserFieldIndex.UserID, 0, 0, 10); + } + /// Inits SectionEntity's FieldInfo objects + private void InitSectionEntityInfos() + { + base.AddElementFieldInfo("SectionEntity", "SectionID", typeof(System.Int32), true, false, true, false, (int)SectionFieldIndex.SectionID, 0, 0, 10); + base.AddElementFieldInfo("SectionEntity", "SectionName", typeof(System.String), false, false, false, false, (int)SectionFieldIndex.SectionName, 50, 0, 0); + base.AddElementFieldInfo("SectionEntity", "SectionDescription", typeof(System.String), false, false, false, false, (int)SectionFieldIndex.SectionDescription, 250, 0, 0); + base.AddElementFieldInfo("SectionEntity", "OrderNo", typeof(System.Int16), false, false, false, false, (int)SectionFieldIndex.OrderNo, 0, 0, 5); + } + /// Inits SupportQueueEntity's FieldInfo objects + private void InitSupportQueueEntityInfos() + { + base.AddElementFieldInfo("SupportQueueEntity", "QueueID", typeof(System.Int32), true, false, true, false, (int)SupportQueueFieldIndex.QueueID, 0, 0, 10); + base.AddElementFieldInfo("SupportQueueEntity", "QueueName", typeof(System.String), false, false, false, true, (int)SupportQueueFieldIndex.QueueName, 50, 0, 0); + base.AddElementFieldInfo("SupportQueueEntity", "QueueDescription", typeof(System.String), false, false, false, true, (int)SupportQueueFieldIndex.QueueDescription, 250, 0, 0); + base.AddElementFieldInfo("SupportQueueEntity", "OrderNo", typeof(System.Int16), false, false, false, false, (int)SupportQueueFieldIndex.OrderNo, 0, 0, 5); + } + /// Inits SupportQueueThreadEntity's FieldInfo objects + private void InitSupportQueueThreadEntityInfos() + { + base.AddElementFieldInfo("SupportQueueThreadEntity", "QueueID", typeof(System.Int32), true, true, false, false, (int)SupportQueueThreadFieldIndex.QueueID, 0, 0, 10); + base.AddElementFieldInfo("SupportQueueThreadEntity", "ThreadID", typeof(System.Int32), true, true, false, false, (int)SupportQueueThreadFieldIndex.ThreadID, 0, 0, 10); + base.AddElementFieldInfo("SupportQueueThreadEntity", "PlacedInQueueByUserID", typeof(System.Int32), false, true, false, false, (int)SupportQueueThreadFieldIndex.PlacedInQueueByUserID, 0, 0, 10); + base.AddElementFieldInfo("SupportQueueThreadEntity", "PlacedInQueueOn", typeof(System.DateTime), false, false, false, false, (int)SupportQueueThreadFieldIndex.PlacedInQueueOn, 0, 3, 23); + base.AddElementFieldInfo("SupportQueueThreadEntity", "ClaimedByUserID", typeof(Nullable), false, true, false, true, (int)SupportQueueThreadFieldIndex.ClaimedByUserID, 0, 0, 10); + base.AddElementFieldInfo("SupportQueueThreadEntity", "ClaimedOn", typeof(Nullable), false, false, false, true, (int)SupportQueueThreadFieldIndex.ClaimedOn, 0, 3, 23); + } + /// Inits SystemDataEntity's FieldInfo objects + private void InitSystemDataEntityInfos() + { + base.AddElementFieldInfo("SystemDataEntity", "ID", typeof(System.Int32), true, false, true, false, (int)SystemDataFieldIndex.ID, 0, 0, 10); + base.AddElementFieldInfo("SystemDataEntity", "DefaultRoleNewUser", typeof(System.Int32), false, true, false, false, (int)SystemDataFieldIndex.DefaultRoleNewUser, 0, 0, 10); + base.AddElementFieldInfo("SystemDataEntity", "AnonymousRole", typeof(System.Int32), false, true, false, false, (int)SystemDataFieldIndex.AnonymousRole, 0, 0, 10); + base.AddElementFieldInfo("SystemDataEntity", "DefaultUserTitleNewUser", typeof(System.Int32), false, false, false, false, (int)SystemDataFieldIndex.DefaultUserTitleNewUser, 0, 0, 10); + base.AddElementFieldInfo("SystemDataEntity", "HoursThresholdForActiveThreads", typeof(System.Int16), false, false, false, false, (int)SystemDataFieldIndex.HoursThresholdForActiveThreads, 0, 0, 5); + base.AddElementFieldInfo("SystemDataEntity", "PageSizeSearchResults", typeof(System.Int16), false, false, false, false, (int)SystemDataFieldIndex.PageSizeSearchResults, 0, 0, 5); + base.AddElementFieldInfo("SystemDataEntity", "MinNumberOfThreadsToFetch", typeof(System.Int16), false, false, false, false, (int)SystemDataFieldIndex.MinNumberOfThreadsToFetch, 0, 0, 5); + base.AddElementFieldInfo("SystemDataEntity", "MinNumberOfNonStickyVisibleThreads", typeof(System.Int16), false, false, false, false, (int)SystemDataFieldIndex.MinNumberOfNonStickyVisibleThreads, 0, 0, 5); + base.AddElementFieldInfo("SystemDataEntity", "SendReplyNotifications", typeof(System.Boolean), false, false, false, false, (int)SystemDataFieldIndex.SendReplyNotifications, 0, 0, 1); + } + /// Inits ThreadEntity's FieldInfo objects + private void InitThreadEntityInfos() + { + base.AddElementFieldInfo("ThreadEntity", "ThreadID", typeof(System.Int32), true, false, true, false, (int)ThreadFieldIndex.ThreadID, 0, 0, 10); + base.AddElementFieldInfo("ThreadEntity", "ForumID", typeof(System.Int32), false, true, false, false, (int)ThreadFieldIndex.ForumID, 0, 0, 10); + base.AddElementFieldInfo("ThreadEntity", "Subject", typeof(System.String), false, false, false, false, (int)ThreadFieldIndex.Subject, 250, 0, 0); + base.AddElementFieldInfo("ThreadEntity", "StartedByUserID", typeof(System.Int32), false, true, false, false, (int)ThreadFieldIndex.StartedByUserID, 0, 0, 10); + base.AddElementFieldInfo("ThreadEntity", "ThreadLastPostingDate", typeof(Nullable), false, false, false, true, (int)ThreadFieldIndex.ThreadLastPostingDate, 0, 3, 23); + base.AddElementFieldInfo("ThreadEntity", "IsSticky", typeof(System.Boolean), false, false, false, false, (int)ThreadFieldIndex.IsSticky, 0, 0, 1); + base.AddElementFieldInfo("ThreadEntity", "IsClosed", typeof(System.Boolean), false, false, false, false, (int)ThreadFieldIndex.IsClosed, 0, 0, 1); + base.AddElementFieldInfo("ThreadEntity", "MarkedAsDone", typeof(System.Boolean), false, false, false, false, (int)ThreadFieldIndex.MarkedAsDone, 0, 0, 1); + base.AddElementFieldInfo("ThreadEntity", "NumberOfViews", typeof(Nullable), false, false, false, true, (int)ThreadFieldIndex.NumberOfViews, 0, 0, 10); + base.AddElementFieldInfo("ThreadEntity", "Memo", typeof(System.String), false, false, false, true, (int)ThreadFieldIndex.Memo, 1073741823, 0, 0); + } + /// Inits ThreadSubscriptionEntity's FieldInfo objects + private void InitThreadSubscriptionEntityInfos() + { + base.AddElementFieldInfo("ThreadSubscriptionEntity", "UserID", typeof(System.Int32), true, true, false, false, (int)ThreadSubscriptionFieldIndex.UserID, 0, 0, 10); + base.AddElementFieldInfo("ThreadSubscriptionEntity", "ThreadID", typeof(System.Int32), true, true, false, false, (int)ThreadSubscriptionFieldIndex.ThreadID, 0, 0, 10); + } + /// Inits UserEntity's FieldInfo objects + private void InitUserEntityInfos() + { + base.AddElementFieldInfo("UserEntity", "UserID", typeof(System.Int32), true, false, true, false, (int)UserFieldIndex.UserID, 0, 0, 10); + base.AddElementFieldInfo("UserEntity", "NickName", typeof(System.String), false, false, false, false, (int)UserFieldIndex.NickName, 20, 0, 0); + base.AddElementFieldInfo("UserEntity", "Password", typeof(System.String), false, false, false, false, (int)UserFieldIndex.Password, 30, 0, 0); + base.AddElementFieldInfo("UserEntity", "IsBanned", typeof(System.Boolean), false, false, false, false, (int)UserFieldIndex.IsBanned, 0, 0, 1); + base.AddElementFieldInfo("UserEntity", "IPNumber", typeof(System.String), false, false, false, false, (int)UserFieldIndex.IPNumber, 25, 0, 0); + base.AddElementFieldInfo("UserEntity", "Signature", typeof(System.String), false, false, false, true, (int)UserFieldIndex.Signature, 250, 0, 0); + base.AddElementFieldInfo("UserEntity", "IconURL", typeof(System.String), false, false, false, true, (int)UserFieldIndex.IconURL, 250, 0, 0); + base.AddElementFieldInfo("UserEntity", "EmailAddress", typeof(System.String), false, false, false, true, (int)UserFieldIndex.EmailAddress, 200, 0, 0); + base.AddElementFieldInfo("UserEntity", "UserTitleID", typeof(System.Int32), false, true, false, false, (int)UserFieldIndex.UserTitleID, 0, 0, 10); + base.AddElementFieldInfo("UserEntity", "DateOfBirth", typeof(Nullable), false, false, false, true, (int)UserFieldIndex.DateOfBirth, 0, 3, 23); + base.AddElementFieldInfo("UserEntity", "Occupation", typeof(System.String), false, false, false, true, (int)UserFieldIndex.Occupation, 100, 0, 0); + base.AddElementFieldInfo("UserEntity", "Location", typeof(System.String), false, false, false, true, (int)UserFieldIndex.Location, 100, 0, 0); + base.AddElementFieldInfo("UserEntity", "Website", typeof(System.String), false, false, false, true, (int)UserFieldIndex.Website, 200, 0, 0); + base.AddElementFieldInfo("UserEntity", "SignatureAsHTML", typeof(System.String), false, false, false, true, (int)UserFieldIndex.SignatureAsHTML, 1024, 0, 0); + base.AddElementFieldInfo("UserEntity", "JoinDate", typeof(Nullable), false, false, false, true, (int)UserFieldIndex.JoinDate, 0, 3, 23); + base.AddElementFieldInfo("UserEntity", "AmountOfPostings", typeof(Nullable), false, false, false, true, (int)UserFieldIndex.AmountOfPostings, 0, 0, 10); + base.AddElementFieldInfo("UserEntity", "EmailAddressIsPublic", typeof(Nullable), false, false, false, true, (int)UserFieldIndex.EmailAddressIsPublic, 0, 0, 1); + base.AddElementFieldInfo("UserEntity", "LastVisitedDate", typeof(Nullable), false, false, false, true, (int)UserFieldIndex.LastVisitedDate, 0, 3, 23); + base.AddElementFieldInfo("UserEntity", "AutoSubscribeToThread", typeof(System.Boolean), false, false, false, true, (int)UserFieldIndex.AutoSubscribeToThread, 0, 0, 1); + base.AddElementFieldInfo("UserEntity", "DefaultNumberOfMessagesPerPage", typeof(System.Int16), false, false, false, true, (int)UserFieldIndex.DefaultNumberOfMessagesPerPage, 0, 0, 5); + } + /// Inits UserTitleEntity's FieldInfo objects + private void InitUserTitleEntityInfos() + { + base.AddElementFieldInfo("UserTitleEntity", "UserTitleID", typeof(System.Int32), true, false, true, false, (int)UserTitleFieldIndex.UserTitleID, 0, 0, 10); + base.AddElementFieldInfo("UserTitleEntity", "UserTitleDescription", typeof(System.String), false, false, false, false, (int)UserTitleFieldIndex.UserTitleDescription, 50, 0, 0); + } + + } +} + + + + diff --git a/DAL/HelperClasses/InheritanceInfoProvider.cs b/DAL/HelperClasses/InheritanceInfoProvider.cs new file mode 100644 index 0000000..212a19a --- /dev/null +++ b/DAL/HelperClasses/InheritanceInfoProvider.cs @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.RelationClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Singleton implementation of the inheritanceInfoProvider. This class is the singleton wrapper through which the actual instance is retrieved. + /// + /// It uses a single instance of an internal class. The access isn't marked with locks as the InheritanceInfoProviderBase class is threadsafe. + public sealed class InheritanceInfoProviderSingleton + { + #region Class Member Declarations + private static readonly IInheritanceInfoProvider _providerInstance = new InheritanceInfoProviderCore(); + #endregion + + /// private ctor to prevent instances of this class. + private InheritanceInfoProviderSingleton() + { + } + + /// Dummy static constructor to make sure threadsafe initialization is performed. + static InheritanceInfoProviderSingleton() + { + } + + /// Gets the singleton instance of the InheritanceInfoProviderCore + /// Instance of the InheritanceInfoProvider. + public static IInheritanceInfoProvider GetInstance() + { + return _providerInstance; + } + + #region Custom InheritanceInfoProviderSingleton code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomInheritanceInfoProviderSingletonCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + } + + + /// Actual implementation of the InheritanceInfoProvider. Used by singleton wrapper. + internal class InheritanceInfoProviderCore : InheritanceInfoProviderBase + { + /// Initializes a new instance of the class. + internal InheritanceInfoProviderCore() + { + Init(); + } + + /// Method which initializes the internal datastores with the structure of hierarchical types. + private void Init() + { + base.AddEntityInfo("AuditDataCoreEntity", string.Empty, new AuditDataCoreRelations(), new AuditDataCoreEntityFactory()); + base.AddEntityInfo("AuditDataMessageRelatedEntity", "AuditDataCoreEntity", new AuditDataMessageRelatedRelations(), new AuditDataMessageRelatedEntityFactory(), (4-4)); + base.AddEntityInfo("AuditDataThreadRelatedEntity", "AuditDataCoreEntity", new AuditDataThreadRelatedRelations(), new AuditDataThreadRelatedEntityFactory(), (4-4)); + base.BuildHierarchyInfoStore(); + } + + /// Gets the entity fields for the entity passed in. Only the fields defined in the entity are returned + /// Name of the entity to grab the fields for + /// array of IEntityFieldCore fields + public override IEntityFieldCore[] GetEntityFields(string entityName) + { + return EntityFieldsFactory.CreateFields(entityName); + } + } +} + + + + diff --git a/DAL/HelperClasses/PersistenceInfoProvider.cs b/DAL/HelperClasses/PersistenceInfoProvider.cs new file mode 100644 index 0000000..917375c --- /dev/null +++ b/DAL/HelperClasses/PersistenceInfoProvider.cs @@ -0,0 +1,325 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SqlServerSpecific.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Data; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + /// + /// Singleton implementation of the PersistenceInfoProvider. This class is the singleton wrapper through which the actual instance is retrieved. + /// + /// It uses a single instance of an internal class. The access isn't marked with locks as the PersistenceInfoProviderBase class is threadsafe. + internal sealed class PersistenceInfoProviderSingleton + { + #region Class Member Declarations + private static readonly IPersistenceInfoProvider _providerInstance = new PersistenceInfoProviderCore(); + #endregion + + /// private ctor to prevent instances of this class. + private PersistenceInfoProviderSingleton() + { + } + + /// Dummy static constructor to make sure threadsafe initialization is performed. + static PersistenceInfoProviderSingleton() + { + } + + /// Gets the singleton instance of the PersistenceInfoProviderCore + /// Instance of the PersistenceInfoProvider. + public static IPersistenceInfoProvider GetInstance() + { + return _providerInstance; + } + } + + /// Actual implementation of the PersistenceInfoProvider. Used by singleton wrapper. + internal class PersistenceInfoProviderCore : PersistenceInfoProviderBase + { + /// Initializes a new instance of the class. + internal PersistenceInfoProviderCore() + { + Init(); + } + + /// Method which initializes the internal datastores with the structure of hierarchical types. + private void Init() + { + base.InitClass((23 + 0)); + InitActionRightEntityMappings(); + InitAttachmentEntityMappings(); + InitAuditActionEntityMappings(); + InitAuditDataCoreEntityMappings(); + InitAuditDataMessageRelatedEntityMappings(); + InitAuditDataThreadRelatedEntityMappings(); + InitBookmarkEntityMappings(); + InitForumEntityMappings(); + InitForumRoleForumActionRightEntityMappings(); + InitIPBanEntityMappings(); + InitMessageEntityMappings(); + InitRoleEntityMappings(); + InitRoleAuditActionEntityMappings(); + InitRoleSystemActionRightEntityMappings(); + InitRoleUserEntityMappings(); + InitSectionEntityMappings(); + InitSupportQueueEntityMappings(); + InitSupportQueueThreadEntityMappings(); + InitSystemDataEntityMappings(); + InitThreadEntityMappings(); + InitThreadSubscriptionEntityMappings(); + InitUserEntityMappings(); + InitUserTitleEntityMappings(); + + } + + + /// Inits ActionRightEntity's mappings + private void InitActionRightEntityMappings() + { + base.AddElementMapping( "ActionRightEntity", "HnD", @"dbo", "ActionRight", 4 ); + base.AddElementFieldMapping( "ActionRightEntity", "ActionRightID", "ActionRightID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "ActionRightEntity", "ActionRightDescription", "ActionRightDescription", false, (int)SqlDbType.NVarChar, 50, 0, 0, false, "", null, typeof(System.String), 1 ); + base.AddElementFieldMapping( "ActionRightEntity", "AppliesToForum", "AppliesToForum", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 2 ); + base.AddElementFieldMapping( "ActionRightEntity", "AppliesToSystem", "AppliesToSystem", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 3 ); + } + /// Inits AttachmentEntity's mappings + private void InitAttachmentEntityMappings() + { + base.AddElementMapping( "AttachmentEntity", "HnD", @"dbo", "Attachment", 7 ); + base.AddElementFieldMapping( "AttachmentEntity", "AttachmentID", "AttachmentID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "AttachmentEntity", "MessageID", "MessageID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + base.AddElementFieldMapping( "AttachmentEntity", "Filename", "Filename", true, (int)SqlDbType.NVarChar, 255, 0, 0, false, "", null, typeof(System.String), 2 ); + base.AddElementFieldMapping( "AttachmentEntity", "Approved", "Approved", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 3 ); + base.AddElementFieldMapping( "AttachmentEntity", "Filecontents", "Filecontents", false, (int)SqlDbType.Image, 2147483647, 0, 0, false, "", null, typeof(System.Byte[]), 4 ); + base.AddElementFieldMapping( "AttachmentEntity", "Filesize", "Filesize", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 5 ); + base.AddElementFieldMapping( "AttachmentEntity", "AddedOn", "AddedOn", false, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 6 ); + } + /// Inits AuditActionEntity's mappings + private void InitAuditActionEntityMappings() + { + base.AddElementMapping( "AuditActionEntity", "HnD", @"dbo", "AuditAction", 2 ); + base.AddElementFieldMapping( "AuditActionEntity", "AuditActionID", "AuditActionID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "AuditActionEntity", "AuditActionDescription", "AuditActionDescription", true, (int)SqlDbType.NVarChar, 50, 0, 0, false, "", null, typeof(System.String), 1 ); + } + /// Inits AuditDataCoreEntity's mappings + private void InitAuditDataCoreEntityMappings() + { + base.AddElementMapping( "AuditDataCoreEntity", "HnD", @"dbo", "AuditDataCore", 4 ); + base.AddElementFieldMapping( "AuditDataCoreEntity", "AuditDataID", "AuditDataID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "AuditDataCoreEntity", "AuditActionID", "AuditActionID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + base.AddElementFieldMapping( "AuditDataCoreEntity", "UserID", "UserID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 2 ); + base.AddElementFieldMapping( "AuditDataCoreEntity", "AuditedOn", "AuditedOn", false, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 3 ); + } + /// Inits AuditDataMessageRelatedEntity's mappings + private void InitAuditDataMessageRelatedEntityMappings() + { + base.AddElementMapping( "AuditDataMessageRelatedEntity", "HnD", @"dbo", "AuditDataMessageRelated", 2 ); + base.AddElementFieldMapping( "AuditDataMessageRelatedEntity", "AuditDataID", "AuditDataID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "AuditDataMessageRelatedEntity", "MessageID", "MessageID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + } + /// Inits AuditDataThreadRelatedEntity's mappings + private void InitAuditDataThreadRelatedEntityMappings() + { + base.AddElementMapping( "AuditDataThreadRelatedEntity", "HnD", @"dbo", "AuditDataThreadRelated", 2 ); + base.AddElementFieldMapping( "AuditDataThreadRelatedEntity", "AuditDataID", "AuditDataID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "AuditDataThreadRelatedEntity", "ThreadID", "ThreadID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + } + /// Inits BookmarkEntity's mappings + private void InitBookmarkEntityMappings() + { + base.AddElementMapping( "BookmarkEntity", "HnD", @"dbo", "Bookmark", 2 ); + base.AddElementFieldMapping( "BookmarkEntity", "ThreadID", "ThreadID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "BookmarkEntity", "UserID", "UserID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + } + /// Inits ForumEntity's mappings + private void InitForumEntityMappings() + { + base.AddElementMapping( "ForumEntity", "HnD", @"dbo", "Forum", 13 ); + base.AddElementFieldMapping( "ForumEntity", "ForumID", "ForumID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "ForumEntity", "SectionID", "SectionID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + base.AddElementFieldMapping( "ForumEntity", "ForumName", "ForumName", false, (int)SqlDbType.NVarChar, 50, 0, 0, false, "", null, typeof(System.String), 2 ); + base.AddElementFieldMapping( "ForumEntity", "ForumDescription", "ForumDescription", false, (int)SqlDbType.NVarChar, 250, 0, 0, false, "", null, typeof(System.String), 3 ); + base.AddElementFieldMapping( "ForumEntity", "ForumLastPostingDate", "ForumLastPostingDate", true, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 4 ); + base.AddElementFieldMapping( "ForumEntity", "HasRSSFeed", "HasRSSFeed", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 5 ); + base.AddElementFieldMapping( "ForumEntity", "DefaultSupportQueueID", "DefaultSupportQueueID", true, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 6 ); + base.AddElementFieldMapping( "ForumEntity", "DefaultThreadListInterval", "DefaultThreadListInterval", false, (int)SqlDbType.TinyInt, 0, 0, 3, false, "", null, typeof(System.Byte), 7 ); + base.AddElementFieldMapping( "ForumEntity", "OrderNo", "OrderNo", false, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 8 ); + base.AddElementFieldMapping( "ForumEntity", "MaxAttachmentSize", "MaxAttachmentSize", true, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 9 ); + base.AddElementFieldMapping( "ForumEntity", "MaxNoOfAttachmentsPerMessage", "MaxNoOfAttachmentsPerMessage", true, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 10 ); + base.AddElementFieldMapping( "ForumEntity", "NewThreadWelcomeText", "NewThreadWelcomeText", true, (int)SqlDbType.NText, 1073741823, 0, 0, false, "", null, typeof(System.String), 11 ); + base.AddElementFieldMapping( "ForumEntity", "NewThreadWelcomeTextAsHTML", "NewThreadWelcomeTextAsHTML", true, (int)SqlDbType.NText, 1073741823, 0, 0, false, "", null, typeof(System.String), 12 ); + } + /// Inits ForumRoleForumActionRightEntity's mappings + private void InitForumRoleForumActionRightEntityMappings() + { + base.AddElementMapping( "ForumRoleForumActionRightEntity", "HnD", @"dbo", "ForumRoleForumActionRight", 3 ); + base.AddElementFieldMapping( "ForumRoleForumActionRightEntity", "ForumID", "ForumID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "ForumRoleForumActionRightEntity", "RoleID", "RoleID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + base.AddElementFieldMapping( "ForumRoleForumActionRightEntity", "ActionRightID", "ActionRightID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 2 ); + } + /// Inits IPBanEntity's mappings + private void InitIPBanEntityMappings() + { + base.AddElementMapping( "IPBanEntity", "HnD", @"dbo", "IPBan", 9 ); + base.AddElementFieldMapping( "IPBanEntity", "IPBanID", "IPBanID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "IPBanEntity", "IPSegment1", "IPSegment1", false, (int)SqlDbType.TinyInt, 0, 0, 3, false, "", null, typeof(System.Byte), 1 ); + base.AddElementFieldMapping( "IPBanEntity", "IPSegment2", "IPSegment2", false, (int)SqlDbType.TinyInt, 0, 0, 3, false, "", null, typeof(System.Byte), 2 ); + base.AddElementFieldMapping( "IPBanEntity", "IPSegment3", "IPSegment3", false, (int)SqlDbType.TinyInt, 0, 0, 3, false, "", null, typeof(System.Byte), 3 ); + base.AddElementFieldMapping( "IPBanEntity", "IPSegment4", "IPSegment4", false, (int)SqlDbType.TinyInt, 0, 0, 3, false, "", null, typeof(System.Byte), 4 ); + base.AddElementFieldMapping( "IPBanEntity", "Range", "Range", false, (int)SqlDbType.TinyInt, 0, 0, 3, false, "", null, typeof(System.Byte), 5 ); + base.AddElementFieldMapping( "IPBanEntity", "IPBanSetByUserID", "IPBanSetByUserID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 6 ); + base.AddElementFieldMapping( "IPBanEntity", "IPBanSetOn", "IPBanSetOn", false, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 7 ); + base.AddElementFieldMapping( "IPBanEntity", "Reason", "Reason", false, (int)SqlDbType.NText, 1073741823, 0, 0, false, "", null, typeof(System.String), 8 ); + } + /// Inits MessageEntity's mappings + private void InitMessageEntityMappings() + { + base.AddElementMapping( "MessageEntity", "HnD", @"dbo", "Message", 9 ); + base.AddElementFieldMapping( "MessageEntity", "MessageID", "MessageID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "MessageEntity", "PostingDate", "PostingDate", false, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 1 ); + base.AddElementFieldMapping( "MessageEntity", "PostedByUserID", "PostedByUserID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 2 ); + base.AddElementFieldMapping( "MessageEntity", "ThreadID", "ThreadID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 3 ); + base.AddElementFieldMapping( "MessageEntity", "PostedFromIP", "PostedFromIP", false, (int)SqlDbType.VarChar, 25, 0, 0, false, "", null, typeof(System.String), 4 ); + base.AddElementFieldMapping( "MessageEntity", "ChangeTrackerStamp", "ChangeTrackerStamp", false, (int)SqlDbType.Timestamp, 8, 0, 0, false, "", null, typeof(System.Byte[]), 5 ); + base.AddElementFieldMapping( "MessageEntity", "MessageText", "MessageText", true, (int)SqlDbType.NText, 1073741823, 0, 0, false, "", null, typeof(System.String), 6 ); + base.AddElementFieldMapping( "MessageEntity", "MessageTextAsHTML", "MessageTextAsHTML", true, (int)SqlDbType.NText, 1073741823, 0, 0, false, "", null, typeof(System.String), 7 ); + base.AddElementFieldMapping( "MessageEntity", "MessageTextAsXml", "MessageTextAsXml", true, (int)SqlDbType.NText, 1073741823, 0, 0, false, "", null, typeof(System.String), 8 ); + } + /// Inits RoleEntity's mappings + private void InitRoleEntityMappings() + { + base.AddElementMapping( "RoleEntity", "HnD", @"dbo", "Role", 2 ); + base.AddElementFieldMapping( "RoleEntity", "RoleID", "RoleID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "RoleEntity", "RoleDescription", "RoleDescription", false, (int)SqlDbType.NVarChar, 50, 0, 0, false, "", null, typeof(System.String), 1 ); + } + /// Inits RoleAuditActionEntity's mappings + private void InitRoleAuditActionEntityMappings() + { + base.AddElementMapping( "RoleAuditActionEntity", "HnD", @"dbo", "RoleAuditAction", 2 ); + base.AddElementFieldMapping( "RoleAuditActionEntity", "AuditActionID", "AuditActionID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "RoleAuditActionEntity", "RoleID", "RoleID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + } + /// Inits RoleSystemActionRightEntity's mappings + private void InitRoleSystemActionRightEntityMappings() + { + base.AddElementMapping( "RoleSystemActionRightEntity", "HnD", @"dbo", "RoleSystemActionRight", 2 ); + base.AddElementFieldMapping( "RoleSystemActionRightEntity", "RoleID", "RoleID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "RoleSystemActionRightEntity", "ActionRightID", "ActionRightID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + } + /// Inits RoleUserEntity's mappings + private void InitRoleUserEntityMappings() + { + base.AddElementMapping( "RoleUserEntity", "HnD", @"dbo", "RoleUser", 2 ); + base.AddElementFieldMapping( "RoleUserEntity", "RoleID", "RoleID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "RoleUserEntity", "UserID", "UserID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + } + /// Inits SectionEntity's mappings + private void InitSectionEntityMappings() + { + base.AddElementMapping( "SectionEntity", "HnD", @"dbo", "Section", 4 ); + base.AddElementFieldMapping( "SectionEntity", "SectionID", "SectionID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "SectionEntity", "SectionName", "SectionName", false, (int)SqlDbType.NVarChar, 50, 0, 0, false, "", null, typeof(System.String), 1 ); + base.AddElementFieldMapping( "SectionEntity", "SectionDescription", "SectionDescription", false, (int)SqlDbType.NVarChar, 250, 0, 0, false, "", null, typeof(System.String), 2 ); + base.AddElementFieldMapping( "SectionEntity", "OrderNo", "OrderNo", false, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 3 ); + } + /// Inits SupportQueueEntity's mappings + private void InitSupportQueueEntityMappings() + { + base.AddElementMapping( "SupportQueueEntity", "HnD", @"dbo", "SupportQueue", 4 ); + base.AddElementFieldMapping( "SupportQueueEntity", "QueueID", "QueueID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "SupportQueueEntity", "QueueName", "QueueName", true, (int)SqlDbType.NVarChar, 50, 0, 0, false, "", null, typeof(System.String), 1 ); + base.AddElementFieldMapping( "SupportQueueEntity", "QueueDescription", "QueueDescription", true, (int)SqlDbType.NVarChar, 250, 0, 0, false, "", null, typeof(System.String), 2 ); + base.AddElementFieldMapping( "SupportQueueEntity", "OrderNo", "OrderNo", false, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 3 ); + } + /// Inits SupportQueueThreadEntity's mappings + private void InitSupportQueueThreadEntityMappings() + { + base.AddElementMapping( "SupportQueueThreadEntity", "HnD", @"dbo", "SupportQueueThread", 6 ); + base.AddElementFieldMapping( "SupportQueueThreadEntity", "QueueID", "QueueID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "SupportQueueThreadEntity", "ThreadID", "ThreadID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + base.AddElementFieldMapping( "SupportQueueThreadEntity", "PlacedInQueueByUserID", "PlacedInQueueByUserID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 2 ); + base.AddElementFieldMapping( "SupportQueueThreadEntity", "PlacedInQueueOn", "PlacedInQueueOn", false, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 3 ); + base.AddElementFieldMapping( "SupportQueueThreadEntity", "ClaimedByUserID", "ClaimedByUserID", true, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 4 ); + base.AddElementFieldMapping( "SupportQueueThreadEntity", "ClaimedOn", "ClaimedOn", true, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 5 ); + } + /// Inits SystemDataEntity's mappings + private void InitSystemDataEntityMappings() + { + base.AddElementMapping( "SystemDataEntity", "HnD", @"dbo", "SystemData", 9 ); + base.AddElementFieldMapping( "SystemDataEntity", "ID", "ID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "SystemDataEntity", "DefaultRoleNewUser", "DefaultRoleNewUser", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + base.AddElementFieldMapping( "SystemDataEntity", "AnonymousRole", "AnonymousRole", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 2 ); + base.AddElementFieldMapping( "SystemDataEntity", "DefaultUserTitleNewUser", "DefaultUserTitleNewUser", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 3 ); + base.AddElementFieldMapping( "SystemDataEntity", "HoursThresholdForActiveThreads", "HoursThresholdForActiveThreads", false, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 4 ); + base.AddElementFieldMapping( "SystemDataEntity", "PageSizeSearchResults", "PageSizeSearchResults", false, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 5 ); + base.AddElementFieldMapping( "SystemDataEntity", "MinNumberOfThreadsToFetch", "MinNumberOfThreadsToFetch", false, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 6 ); + base.AddElementFieldMapping( "SystemDataEntity", "MinNumberOfNonStickyVisibleThreads", "MinNumberOfNonStickyVisibleThreads", false, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 7 ); + base.AddElementFieldMapping( "SystemDataEntity", "SendReplyNotifications", "SendReplyNotifications", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 8 ); + } + /// Inits ThreadEntity's mappings + private void InitThreadEntityMappings() + { + base.AddElementMapping( "ThreadEntity", "HnD", @"dbo", "Thread", 10 ); + base.AddElementFieldMapping( "ThreadEntity", "ThreadID", "ThreadID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "ThreadEntity", "ForumID", "ForumID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + base.AddElementFieldMapping( "ThreadEntity", "Subject", "Subject", false, (int)SqlDbType.NVarChar, 250, 0, 0, false, "", null, typeof(System.String), 2 ); + base.AddElementFieldMapping( "ThreadEntity", "StartedByUserID", "StartedByUserID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 3 ); + base.AddElementFieldMapping( "ThreadEntity", "ThreadLastPostingDate", "ThreadLastPostingDate", true, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 4 ); + base.AddElementFieldMapping( "ThreadEntity", "IsSticky", "IsSticky", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 5 ); + base.AddElementFieldMapping( "ThreadEntity", "IsClosed", "IsClosed", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 6 ); + base.AddElementFieldMapping( "ThreadEntity", "MarkedAsDone", "MarkedAsDone", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 7 ); + base.AddElementFieldMapping( "ThreadEntity", "NumberOfViews", "NumberOfViews", true, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 8 ); + base.AddElementFieldMapping( "ThreadEntity", "Memo", "Memo", true, (int)SqlDbType.NText, 1073741823, 0, 0, false, "", null, typeof(System.String), 9 ); + } + /// Inits ThreadSubscriptionEntity's mappings + private void InitThreadSubscriptionEntityMappings() + { + base.AddElementMapping( "ThreadSubscriptionEntity", "HnD", @"dbo", "ThreadSubscription", 2 ); + base.AddElementFieldMapping( "ThreadSubscriptionEntity", "UserID", "UserID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "ThreadSubscriptionEntity", "ThreadID", "ThreadID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 1 ); + } + /// Inits UserEntity's mappings + private void InitUserEntityMappings() + { + base.AddElementMapping( "UserEntity", "HnD", @"dbo", "User", 20 ); + base.AddElementFieldMapping( "UserEntity", "UserID", "UserID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "UserEntity", "NickName", "NickName", false, (int)SqlDbType.NVarChar, 20, 0, 0, false, "", null, typeof(System.String), 1 ); + base.AddElementFieldMapping( "UserEntity", "Password", "Password", false, (int)SqlDbType.NVarChar, 30, 0, 0, false, "", null, typeof(System.String), 2 ); + base.AddElementFieldMapping( "UserEntity", "IsBanned", "IsBanned", false, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 3 ); + base.AddElementFieldMapping( "UserEntity", "IPNumber", "IPNumber", false, (int)SqlDbType.VarChar, 25, 0, 0, false, "", null, typeof(System.String), 4 ); + base.AddElementFieldMapping( "UserEntity", "Signature", "Signature", true, (int)SqlDbType.NVarChar, 250, 0, 0, false, "", null, typeof(System.String), 5 ); + base.AddElementFieldMapping( "UserEntity", "IconURL", "IconURL", true, (int)SqlDbType.NVarChar, 250, 0, 0, false, "", null, typeof(System.String), 6 ); + base.AddElementFieldMapping( "UserEntity", "EmailAddress", "EmailAddress", true, (int)SqlDbType.NVarChar, 200, 0, 0, false, "", null, typeof(System.String), 7 ); + base.AddElementFieldMapping( "UserEntity", "UserTitleID", "UserTitleID", false, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 8 ); + base.AddElementFieldMapping( "UserEntity", "DateOfBirth", "DateOfBirth", true, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 9 ); + base.AddElementFieldMapping( "UserEntity", "Occupation", "Occupation", true, (int)SqlDbType.NVarChar, 100, 0, 0, false, "", null, typeof(System.String), 10 ); + base.AddElementFieldMapping( "UserEntity", "Location", "Location", true, (int)SqlDbType.NVarChar, 100, 0, 0, false, "", null, typeof(System.String), 11 ); + base.AddElementFieldMapping( "UserEntity", "Website", "Website", true, (int)SqlDbType.NVarChar, 200, 0, 0, false, "", null, typeof(System.String), 12 ); + base.AddElementFieldMapping( "UserEntity", "SignatureAsHTML", "SignatureAsHTML", true, (int)SqlDbType.NVarChar, 1024, 0, 0, false, "", null, typeof(System.String), 13 ); + base.AddElementFieldMapping( "UserEntity", "JoinDate", "JoinDate", true, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 14 ); + base.AddElementFieldMapping( "UserEntity", "AmountOfPostings", "AmountOfPostings", true, (int)SqlDbType.Int, 0, 0, 10, false, "", null, typeof(System.Int32), 15 ); + base.AddElementFieldMapping( "UserEntity", "EmailAddressIsPublic", "EmailAddressIsPublic", true, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 16 ); + base.AddElementFieldMapping( "UserEntity", "LastVisitedDate", "LastVisitedDate", true, (int)SqlDbType.DateTime, 0, 3, 23, false, "", null, typeof(System.DateTime), 17 ); + base.AddElementFieldMapping( "UserEntity", "AutoSubscribeToThread", "AutoSubscribeToThread", true, (int)SqlDbType.Bit, 0, 0, 1, false, "", null, typeof(System.Boolean), 18 ); + base.AddElementFieldMapping( "UserEntity", "DefaultNumberOfMessagesPerPage", "DefaultNumberOfMessagesPerPage", true, (int)SqlDbType.SmallInt, 0, 0, 5, false, "", null, typeof(System.Int16), 19 ); + } + /// Inits UserTitleEntity's mappings + private void InitUserTitleEntityMappings() + { + base.AddElementMapping( "UserTitleEntity", "HnD", @"dbo", "UserTitle", 2 ); + base.AddElementFieldMapping( "UserTitleEntity", "UserTitleID", "UserTitleID", false, (int)SqlDbType.Int, 0, 0, 10, true, "SCOPE_IDENTITY()", null, typeof(System.Int32), 0 ); + base.AddElementFieldMapping( "UserTitleEntity", "UserTitleDescription", "UserTitleDescription", false, (int)SqlDbType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 1 ); + } + + } +} \ No newline at end of file diff --git a/DAL/HelperClasses/ResultsetFields.cs b/DAL/HelperClasses/ResultsetFields.cs new file mode 100644 index 0000000..05550e3 --- /dev/null +++ b/DAL/HelperClasses/ResultsetFields.cs @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +#if !CF +using System.Runtime.Serialization; +#endif +using System.Collections; +using SD.HnD.DAL.FactoryClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + /// + /// Helper class which will eases the creation of custom made resultsets. Usable in typed lists + /// and dynamic lists created using the dynamic query engine. + /// + [Serializable] + public partial class ResultsetFields : EntityFields, ISerializable + { + /// CTor + public ResultsetFields(int amountFields) : base(amountFields, InheritanceInfoProviderSingleton.GetInstance(), null) + { + } + + /// Deserialization constructor + /// Info. + /// Context. + protected ResultsetFields(SerializationInfo info, StreamingContext context):base((int)info.GetInt32("_amountFields"), InheritanceInfoProviderSingleton.GetInstance(), null) + { + ArrayList fields = (ArrayList)info.GetValue("_fields", typeof(ArrayList)); + for (int i = 0; i < fields.Count; i++) + { + this[i] = (IEntityField)fields[i]; + } + } + + /// Populates a with the data needed to serialize the target object. + /// The to populate with data. + /// The destination (see ) for this serialization. + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("_amountFields", this.Count); + ArrayList fields = new ArrayList(this.Count); + for (int i = 0; i < this.Count; i++) + { + fields.Add(this[i]); + } + info.AddValue("_fields", fields, typeof(ArrayList)); + } + + #region Included Code + + #endregion + } +} diff --git a/DAL/HelperClasses/Transaction.cs b/DAL/HelperClasses/Transaction.cs new file mode 100644 index 0000000..ff73a9a --- /dev/null +++ b/DAL/HelperClasses/Transaction.cs @@ -0,0 +1,83 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; + +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + /// + /// Specific implementation of the Transaction class. The constructor will take care of the creation of the physical transaction and the + /// opening of the connection. The transaction object is ready to use as soon as the constructor succeeds. + /// + public partial class Transaction : TransactionBase + { + /// + /// CTor. Will read the connection string from an external source. Opens connection, class + /// + /// IsolationLevel to use in the transaction + /// The name of the transaction to use. + public Transaction(IsolationLevel transactionIsolationLevel, string name):base(transactionIsolationLevel, name) + { + // empty + } + + + /// + /// CTor. + /// + /// IsolationLevel to use in the transaction + /// The name of the transaction to use. + /// Connection string to use in this transaction + public Transaction(IsolationLevel transactionIsolationLevel, string name, string connectionString):base(transactionIsolationLevel, name, connectionString) + { + // empty + } + + + /// + /// Creates a new IDbConnection instance which will be used by all elements using this ITransaction instance. + /// Reads connectionstring from .config file. + /// + /// new IDbConnection instance + protected override System.Data.IDbConnection CreateConnection() + { + return DbUtils.CreateConnection(); + } + + + /// + /// Creates a new IDbConnection instance which will be used by all elements using this ITransaction instance + /// + /// Connection string to use + /// new IDbConnection instance + protected override System.Data.IDbConnection CreateConnection(string connectionString) + { + return DbUtils.CreateConnection(connectionString); + } + + + /// + /// Creates a new physical transaction object over the created connection. The connection is assumed to be open. + /// + /// a physical transaction object, like an instance of SqlTransaction. + protected override System.Data.IDbTransaction CreatePhysicalTransaction() + { + return DbUtils.CreateTransaction(base.ConnectionToUse, base.TransactionIsolationLevel, this.Name); + } + + #region Included Code + + #endregion + } +} diff --git a/DAL/HelperClasses/TransactionComPlus.cs b/DAL/HelperClasses/TransactionComPlus.cs new file mode 100644 index 0000000..47ba31a --- /dev/null +++ b/DAL/HelperClasses/TransactionComPlus.cs @@ -0,0 +1,77 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +#if !CEDesktop +using System; +using System.Data; +using System.EnterpriseServices; + +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + /// + /// Specific implementation of the TransactionComPlus class. The constructor will take care of the creation of the physical transaction and the + /// opening of the connection. It will require a COM+ transaction. + /// + [MustRunInClientContext(true)] + public partial class TransactionComPlus : TransactionComPlusBase + { + /// + /// CTor + /// + public TransactionComPlus() + { + } + + + + /// + /// Creates a new IDbConnection instance which will be used by all elements using this ITransaction instance. + /// Reads connectionstring from .config file. The COM+ transaction will flow to the used method. + /// + /// new IDbConnection instance + protected override System.Data.IDbConnection CreateConnection() + { + DbUtilsComPlus dbUtilsToUse = new DbUtilsComPlus(); + return dbUtilsToUse.CreateConnection(); + } + + + /// + /// Creates a new IDbConnection instance which will be used by all elements using this ITransaction instance + /// The COM+ transaction will flow to the used method. + /// + /// Connection string to use + /// new IDbConnection instance + protected override System.Data.IDbConnection CreateConnection(string connectionString) + { + DbUtilsComPlus dbUtilsToUse = new DbUtilsComPlus(); + return dbUtilsToUse.CreateConnection(connectionString); + } + + + /// + /// Creates a new physical transaction object over the created connection. The connection is assumed to be open. + /// This method is void in combination of a COM+ transaction. It will always return null. + /// + /// null + protected override System.Data.IDbTransaction CreatePhysicalTransaction() + { + return null; + } + + #region Included Code + + #endregion + } +} +#endif \ No newline at end of file diff --git a/DAL/HelperClasses/TypeDefaultValue.cs b/DAL/HelperClasses/TypeDefaultValue.cs new file mode 100644 index 0000000..48e8b74 --- /dev/null +++ b/DAL/HelperClasses/TypeDefaultValue.cs @@ -0,0 +1,112 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.HelperClasses +{ + /// + /// Class for the returning of a default value when a type is given. These + /// Default values are used for EntityFields which have a NULL value in the database. + /// In Business Logic it's impractical to work with NULL values. If you want different values + /// as default values for NULL values for a given type, alter the DefaultValue method below. + /// If you want to keep your values when regenerating the code, make this file read-only, or bind a different + /// template to the template ID: SD_TypeDefaultValueIncludeTemplate, or alter the template file currently + /// bound to that template ID. + /// + [Serializable] + public partial class TypeDefaultValue : ITypeDefaultValue + { + /// + /// Ctor + /// + public TypeDefaultValue() + { + } + + + /// + /// Returns a default value for the type specified + /// + /// The type which default value should be returned. + /// The default value for the type specified. + public object DefaultValue(System.Type defaultValueType) + { + return TypeDefaultValue.GetDefaultValue(defaultValueType); + } + + + /// + /// Returns a default value for the type specified + /// + /// The type which default value should be returned. + /// The default value for the type specified. + public static object GetDefaultValue(System.Type defaultValueType) + { + object valueToReturn=null; + + switch(Type.GetTypeCode(defaultValueType)) + { + case TypeCode.String: + valueToReturn=string.Empty; + break; + case TypeCode.Boolean: + valueToReturn = false; + break; + case TypeCode.Byte: + valueToReturn = (byte)0; + break; + case TypeCode.DateTime: + valueToReturn = DateTime.MinValue; + break; + case TypeCode.Decimal: + valueToReturn = 0.0M; + break; + case TypeCode.Double: + valueToReturn = 0.0; + break; + case TypeCode.Int16: + valueToReturn = (short)0; + break; + case TypeCode.Int32: + valueToReturn = (int)0; + break; + case TypeCode.Int64: + valueToReturn = (long)0; + break; + case TypeCode.Object: + switch(defaultValueType.UnderlyingSystemType.FullName) + { + case "System.Guid": + valueToReturn = Guid.Empty; + break; + case "System.Byte[]": + valueToReturn = new byte[0]; + break; + } + break; + case TypeCode.Single: + valueToReturn = 0.0f; + break; + default: + // do nothing, return null. + break; + } + return valueToReturn; + + } + + #region Included Code + + #endregion + } +} + diff --git a/DAL/LICENSE.txt b/DAL/LICENSE.txt new file mode 100644 index 0000000..e69de29 diff --git a/DAL/RelationClasses/ActionRightRelations.cs b/DAL/RelationClasses/ActionRightRelations.cs new file mode 100644 index 0000000..d80a7a7 --- /dev/null +++ b/DAL/RelationClasses/ActionRightRelations.cs @@ -0,0 +1,85 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: ActionRight. + public partial class ActionRightRelations + { + /// CTor + public ActionRightRelations() + { + } + + /// Gets all relations of the ActionRightEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.ForumRoleForumActionRightEntityUsingActionRightID); + toReturn.Add(this.RoleSystemActionRightEntityUsingActionRightID); + + + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between ActionRightEntity and ForumRoleForumActionRightEntity over the 1:n relation they have, using the relation between the fields: + /// ActionRight.ActionRightID - ForumRoleForumActionRight.ActionRightID + /// + public virtual IEntityRelation ForumRoleForumActionRightEntityUsingActionRightID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "ForumRoleForumActionRights" , true); + relation.AddEntityFieldPair(ActionRightFields.ActionRightID, ForumRoleForumActionRightFields.ActionRightID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ActionRightEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumRoleForumActionRightEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between ActionRightEntity and RoleSystemActionRightEntity over the 1:n relation they have, using the relation between the fields: + /// ActionRight.ActionRightID - RoleSystemActionRight.ActionRightID + /// + public virtual IEntityRelation RoleSystemActionRightEntityUsingActionRightID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "RoleSystemActionRights" , true); + relation.AddEntityFieldPair(ActionRightFields.ActionRightID, RoleSystemActionRightFields.ActionRightID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ActionRightEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleSystemActionRightEntity", false); + return relation; + } + } + + + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/AttachmentRelations.cs b/DAL/RelationClasses/AttachmentRelations.cs new file mode 100644 index 0000000..9b537ff --- /dev/null +++ b/DAL/RelationClasses/AttachmentRelations.cs @@ -0,0 +1,69 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: Attachment. + public partial class AttachmentRelations + { + /// CTor + public AttachmentRelations() + { + } + + /// Gets all relations of the AttachmentEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.MessageEntityUsingMessageID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between AttachmentEntity and MessageEntity over the m:1 relation they have, using the relation between the fields: + /// Attachment.MessageID - Message.MessageID + /// + public virtual IEntityRelation MessageEntityUsingMessageID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "BelongsToMessage", false); + relation.AddEntityFieldPair(MessageFields.MessageID, AttachmentFields.MessageID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("MessageEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AttachmentEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/AuditActionRelations.cs b/DAL/RelationClasses/AuditActionRelations.cs new file mode 100644 index 0000000..9b76b48 --- /dev/null +++ b/DAL/RelationClasses/AuditActionRelations.cs @@ -0,0 +1,85 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: AuditAction. + public partial class AuditActionRelations + { + /// CTor + public AuditActionRelations() + { + } + + /// Gets all relations of the AuditActionEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.AuditDataCoreEntityUsingAuditActionID); + toReturn.Add(this.RoleAuditActionEntityUsingAuditActionID); + + + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between AuditActionEntity and AuditDataCoreEntity over the 1:n relation they have, using the relation between the fields: + /// AuditAction.AuditActionID - AuditDataCore.AuditActionID + /// + public virtual IEntityRelation AuditDataCoreEntityUsingAuditActionID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "AuditDataCore" , true); + relation.AddEntityFieldPair(AuditActionFields.AuditActionID, AuditDataCoreFields.AuditActionID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditActionEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataCoreEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between AuditActionEntity and RoleAuditActionEntity over the 1:n relation they have, using the relation between the fields: + /// AuditAction.AuditActionID - RoleAuditAction.AuditActionID + /// + public virtual IEntityRelation RoleAuditActionEntityUsingAuditActionID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "RoleAuditActions" , true); + relation.AddEntityFieldPair(AuditActionFields.AuditActionID, RoleAuditActionFields.AuditActionID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditActionEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleAuditActionEntity", false); + return relation; + } + } + + + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/AuditDataCoreRelations.cs b/DAL/RelationClasses/AuditDataCoreRelations.cs new file mode 100644 index 0000000..7264f12 --- /dev/null +++ b/DAL/RelationClasses/AuditDataCoreRelations.cs @@ -0,0 +1,137 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: AuditDataCore. + public partial class AuditDataCoreRelations : IRelationFactory + { + /// CTor + public AuditDataCoreRelations() + { + } + + /// Gets all relations of the AuditDataCoreEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.AuditActionEntityUsingAuditActionID); + toReturn.Add(this.UserEntityUsingUserID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between AuditDataCoreEntity and AuditActionEntity over the m:1 relation they have, using the relation between the fields: + /// AuditDataCore.AuditActionID - AuditAction.AuditActionID + /// + public virtual IEntityRelation AuditActionEntityUsingAuditActionID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "AuditAction", false); + relation.AddEntityFieldPair(AuditActionFields.AuditActionID, AuditDataCoreFields.AuditActionID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditActionEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataCoreEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between AuditDataCoreEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// AuditDataCore.UserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "UserAudited", false); + relation.AddEntityFieldPair(UserFields.UserID, AuditDataCoreFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataCoreEntity", true); + return relation; + } + } + + /// Returns a new IEntityRelation object, between AuditDataCoreEntity and AuditDataMessageRelatedEntity over the 1:1 relation they have, which is used to build a target per entity hierarchy, and is using the relation between the fields: + /// AuditDataCore.AuditDataID - AuditDataMessageRelated.AuditDataID + /// + internal IEntityRelation RelationToSubTypeAuditDataMessageRelatedEntity + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToOne, true); + + relation.AddEntityFieldPair(AuditDataCoreFields.AuditDataID, AuditDataMessageRelatedFields.AuditDataID); + + + + relation.IsHierarchyRelation=true; + return relation; + } + } + /// Returns a new IEntityRelation object, between AuditDataCoreEntity and AuditDataThreadRelatedEntity over the 1:1 relation they have, which is used to build a target per entity hierarchy, and is using the relation between the fields: + /// AuditDataCore.AuditDataID - AuditDataThreadRelated.AuditDataID + /// + internal IEntityRelation RelationToSubTypeAuditDataThreadRelatedEntity + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToOne, true); + + relation.AddEntityFieldPair(AuditDataCoreFields.AuditDataID, AuditDataThreadRelatedFields.AuditDataID); + + + + relation.IsHierarchyRelation=true; + return relation; + } + } + /// Returns the relation object the entity, to which this relation factory belongs, has with the subtype with the specified name + /// name of direct subtype which is a subtype of the current entity through the relation to return. + /// relation which makes the current entity a supertype of the subtype entity with the name specified, or null if not applicable/found + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) + { + switch(subTypeEntityName) + { + case "AuditDataMessageRelatedEntity": + return this.RelationToSubTypeAuditDataMessageRelatedEntity; + case "AuditDataThreadRelatedEntity": + return this.RelationToSubTypeAuditDataThreadRelatedEntity; + default: + return null; + } + } + + + /// Returns the relation object the entity, to which this relation factory belongs, has with its supertype, if applicable. + /// relation which makes the current entity a subtype of its supertype entity or null if not applicable/found + public virtual IEntityRelation GetSuperTypeRelation() + { + return null; + } + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/AuditDataMessageRelatedRelations.cs b/DAL/RelationClasses/AuditDataMessageRelatedRelations.cs new file mode 100644 index 0000000..e2029d7 --- /dev/null +++ b/DAL/RelationClasses/AuditDataMessageRelatedRelations.cs @@ -0,0 +1,125 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: AuditDataMessageRelated. + public partial class AuditDataMessageRelatedRelations : AuditDataCoreRelations + { + /// CTor + public AuditDataMessageRelatedRelations() + { + } + + /// Gets all relations of the AuditDataMessageRelatedEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public override List GetAllRelations() + { + List toReturn = base.GetAllRelations(); + + + toReturn.Add(this.MessageEntityUsingMessageID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between AuditDataMessageRelatedEntity and AuditActionEntity over the m:1 relation they have, using the relation between the fields: + /// AuditDataMessageRelated.AuditActionID - AuditAction.AuditActionID + /// + public override IEntityRelation AuditActionEntityUsingAuditActionID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "AuditAction", false); + relation.AddEntityFieldPair(AuditActionFields.AuditActionID, AuditDataMessageRelatedFields.AuditActionID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditActionEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataMessageRelatedEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between AuditDataMessageRelatedEntity and MessageEntity over the m:1 relation they have, using the relation between the fields: + /// AuditDataMessageRelated.MessageID - Message.MessageID + /// + public virtual IEntityRelation MessageEntityUsingMessageID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Message", false); + relation.AddEntityFieldPair(MessageFields.MessageID, AuditDataMessageRelatedFields.MessageID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("MessageEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataMessageRelatedEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between AuditDataMessageRelatedEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// AuditDataMessageRelated.UserID - User.UserID + /// + public override IEntityRelation UserEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "UserAudited", false); + relation.AddEntityFieldPair(UserFields.UserID, AuditDataMessageRelatedFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataMessageRelatedEntity", true); + return relation; + } + } + + /// Returns a new IEntityRelation object, between AuditDataMessageRelatedEntity and AuditDataCoreEntity over the 1:1 relation they have, which is used to build a target per entity hierarchy, and is using the relation between the fields: + /// AuditDataMessageRelated.AuditDataID - AuditDataCore.AuditDataID + /// + internal IEntityRelation RelationToSuperTypeAuditDataCoreEntity + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToOne, false); + + + + relation.AddEntityFieldPair(AuditDataCoreFields.AuditDataID, AuditDataMessageRelatedFields.AuditDataID); + + relation.IsHierarchyRelation=true; + return relation; + } + } + /// Returns the relation object the entity, to which this relation factory belongs, has with the subtype with the specified name + /// name of direct subtype which is a subtype of the current entity through the relation to return. + /// relation which makes the current entity a supertype of the subtype entity with the name specified, or null if not applicable/found + public override IEntityRelation GetSubTypeRelation(string subTypeEntityName) + { + return null; + } + + + /// Returns the relation object the entity, to which this relation factory belongs, has with its supertype, if applicable. + /// relation which makes the current entity a subtype of its supertype entity or null if not applicable/found + public override IEntityRelation GetSuperTypeRelation() + { + return this.RelationToSuperTypeAuditDataCoreEntity; + } + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/AuditDataThreadRelatedRelations.cs b/DAL/RelationClasses/AuditDataThreadRelatedRelations.cs new file mode 100644 index 0000000..cbc1011 --- /dev/null +++ b/DAL/RelationClasses/AuditDataThreadRelatedRelations.cs @@ -0,0 +1,125 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: AuditDataThreadRelated. + public partial class AuditDataThreadRelatedRelations : AuditDataCoreRelations + { + /// CTor + public AuditDataThreadRelatedRelations() + { + } + + /// Gets all relations of the AuditDataThreadRelatedEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public override List GetAllRelations() + { + List toReturn = base.GetAllRelations(); + + + toReturn.Add(this.ThreadEntityUsingThreadID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between AuditDataThreadRelatedEntity and AuditActionEntity over the m:1 relation they have, using the relation between the fields: + /// AuditDataThreadRelated.AuditActionID - AuditAction.AuditActionID + /// + public override IEntityRelation AuditActionEntityUsingAuditActionID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "AuditAction", false); + relation.AddEntityFieldPair(AuditActionFields.AuditActionID, AuditDataThreadRelatedFields.AuditActionID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditActionEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataThreadRelatedEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between AuditDataThreadRelatedEntity and ThreadEntity over the m:1 relation they have, using the relation between the fields: + /// AuditDataThreadRelated.ThreadID - Thread.ThreadID + /// + public virtual IEntityRelation ThreadEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Thread", false); + relation.AddEntityFieldPair(ThreadFields.ThreadID, AuditDataThreadRelatedFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataThreadRelatedEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between AuditDataThreadRelatedEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// AuditDataThreadRelated.UserID - User.UserID + /// + public override IEntityRelation UserEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "UserAudited", false); + relation.AddEntityFieldPair(UserFields.UserID, AuditDataThreadRelatedFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataThreadRelatedEntity", true); + return relation; + } + } + + /// Returns a new IEntityRelation object, between AuditDataThreadRelatedEntity and AuditDataCoreEntity over the 1:1 relation they have, which is used to build a target per entity hierarchy, and is using the relation between the fields: + /// AuditDataThreadRelated.AuditDataID - AuditDataCore.AuditDataID + /// + internal IEntityRelation RelationToSuperTypeAuditDataCoreEntity + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToOne, false); + + + + relation.AddEntityFieldPair(AuditDataCoreFields.AuditDataID, AuditDataThreadRelatedFields.AuditDataID); + + relation.IsHierarchyRelation=true; + return relation; + } + } + /// Returns the relation object the entity, to which this relation factory belongs, has with the subtype with the specified name + /// name of direct subtype which is a subtype of the current entity through the relation to return. + /// relation which makes the current entity a supertype of the subtype entity with the name specified, or null if not applicable/found + public override IEntityRelation GetSubTypeRelation(string subTypeEntityName) + { + return null; + } + + + /// Returns the relation object the entity, to which this relation factory belongs, has with its supertype, if applicable. + /// relation which makes the current entity a subtype of its supertype entity or null if not applicable/found + public override IEntityRelation GetSuperTypeRelation() + { + return this.RelationToSuperTypeAuditDataCoreEntity; + } + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/BookmarkRelations.cs b/DAL/RelationClasses/BookmarkRelations.cs new file mode 100644 index 0000000..e76fda5 --- /dev/null +++ b/DAL/RelationClasses/BookmarkRelations.cs @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: Bookmark. + public partial class BookmarkRelations + { + /// CTor + public BookmarkRelations() + { + } + + /// Gets all relations of the BookmarkEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.ThreadEntityUsingThreadID); + toReturn.Add(this.UserEntityUsingUserID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between BookmarkEntity and ThreadEntity over the m:1 relation they have, using the relation between the fields: + /// Bookmark.ThreadID - Thread.ThreadID + /// + public virtual IEntityRelation ThreadEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Thread", false); + relation.AddEntityFieldPair(ThreadFields.ThreadID, BookmarkFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("BookmarkEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between BookmarkEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// Bookmark.UserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "User", false); + relation.AddEntityFieldPair(UserFields.UserID, BookmarkFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("BookmarkEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/DynamicRelation.cs b/DAL/RelationClasses/DynamicRelation.cs new file mode 100644 index 0000000..f0aecfb --- /dev/null +++ b/DAL/RelationClasses/DynamicRelation.cs @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +////////////////////////////////////////////////////////////// +using System; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + + /// + /// Class to define dynamic relations for queries. + /// + /// Dynamic relations are only supported in ansi joins. If you're using Oracle on 8i, you can't use Dynamic Relations. In all other cases + /// you can. In the case of Oracle 9i: specify that you want to use Ansi joins (recommended) by setting the config file setting 'OracleAnsiJoins' to true + [Serializable] + public class DynamicRelation : DynamicRelationBase + { + /// Initializes a new instance of the class. + /// The left operand, which can only be a derived table definition. No join will take place. + /// If a DynamicRelation is created with this CTor, it has to be the only one. It will be ignored if there are more + /// relations in the relation collection. + public DynamicRelation(DerivedTableDefinition leftOperand) + { + base.InitClass(JoinHint.None, string.Empty, string.Empty, null, leftOperand, null); + } + + /// + /// Initializes a new instance of the class. + /// + /// The left operand. + /// Type of the join. If None is specified, Inner is assumed. + /// The right operand. + /// The on clause for the join. + public DynamicRelation(DerivedTableDefinition leftOperand, JoinHint joinType, DerivedTableDefinition rightOperand, IPredicate onClause) + { + base.InitClass(joinType, string.Empty, string.Empty, onClause, leftOperand, rightOperand); + } + + /// Initializes a new instance of the class. + /// The left operand. + /// Type of the join. If None is specified, Inner is assumed. + /// The right operand which is an entity type. + /// The alias of the right operand. If you don't want to / need to alias the right operand (only alias if you have to), specify string.Empty. + /// The on clause for the join. + public DynamicRelation(DerivedTableDefinition leftOperand, JoinHint joinType, SD.HnD.DAL.EntityType rightOperand, string aliasRightOperand, IPredicate onClause) + { + base.InitClass(joinType, string.Empty, aliasRightOperand, onClause, leftOperand, GeneralEntityFactory.Create(rightOperand)); + } + + /// Initializes a new instance of the class. + /// The left operand, which is an entity. + /// Type of the join. If None is specified, Inner is assumed. + /// The right operand which is an entity. + /// The alias of the left operand. If you don't want to / need to alias the left operand (only alias if you have to), specify string.Empty. + /// The alias of the right operand. If you don't want to / need to alias the right operand (only alias if you have to), specify string.Empty. + /// The on clause for the join. + public DynamicRelation(SD.HnD.DAL.EntityType leftOperand, JoinHint joinType, SD.HnD.DAL.EntityType rightOperand, string aliasLeftOperand, string aliasRightOperand, IPredicate onClause) + { + base.InitClass(joinType, aliasLeftOperand, aliasRightOperand, onClause, GeneralEntityFactory.Create(leftOperand), GeneralEntityFactory.Create(rightOperand)); + } + + /// Gets the inheritance provider for inheritance info retrieval for entity operands + /// The inheritance info provider + protected override IInheritanceInfoProvider GetInheritanceProvider() + { + return InheritanceInfoProviderSingleton.GetInstance(); + } + } + +} \ No newline at end of file diff --git a/DAL/RelationClasses/ForumRelations.cs b/DAL/RelationClasses/ForumRelations.cs new file mode 100644 index 0000000..363b008 --- /dev/null +++ b/DAL/RelationClasses/ForumRelations.cs @@ -0,0 +1,114 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: Forum. + public partial class ForumRelations + { + /// CTor + public ForumRelations() + { + } + + /// Gets all relations of the ForumEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.ForumRoleForumActionRightEntityUsingForumID); + toReturn.Add(this.ThreadEntityUsingForumID); + + toReturn.Add(this.SectionEntityUsingSectionID); + toReturn.Add(this.SupportQueueEntityUsingDefaultSupportQueueID); + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between ForumEntity and ForumRoleForumActionRightEntity over the 1:n relation they have, using the relation between the fields: + /// Forum.ForumID - ForumRoleForumActionRight.ForumID + /// + public virtual IEntityRelation ForumRoleForumActionRightEntityUsingForumID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "ForumRoleForumActionRights" , true); + relation.AddEntityFieldPair(ForumFields.ForumID, ForumRoleForumActionRightFields.ForumID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumRoleForumActionRightEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between ForumEntity and ThreadEntity over the 1:n relation they have, using the relation between the fields: + /// Forum.ForumID - Thread.ForumID + /// + public virtual IEntityRelation ThreadEntityUsingForumID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "Threads" , true); + relation.AddEntityFieldPair(ForumFields.ForumID, ThreadFields.ForumID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", false); + return relation; + } + } + + + /// Returns a new IEntityRelation object, between ForumEntity and SectionEntity over the m:1 relation they have, using the relation between the fields: + /// Forum.SectionID - Section.SectionID + /// + public virtual IEntityRelation SectionEntityUsingSectionID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Section", false); + relation.AddEntityFieldPair(SectionFields.SectionID, ForumFields.SectionID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SectionEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between ForumEntity and SupportQueueEntity over the m:1 relation they have, using the relation between the fields: + /// Forum.DefaultSupportQueueID - SupportQueue.QueueID + /// + public virtual IEntityRelation SupportQueueEntityUsingDefaultSupportQueueID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "DefaultSupportQueue", false); + relation.AddEntityFieldPair(SupportQueueFields.QueueID, ForumFields.DefaultSupportQueueID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/ForumRoleForumActionRightRelations.cs b/DAL/RelationClasses/ForumRoleForumActionRightRelations.cs new file mode 100644 index 0000000..4de80ce --- /dev/null +++ b/DAL/RelationClasses/ForumRoleForumActionRightRelations.cs @@ -0,0 +1,99 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: ForumRoleForumActionRight. + public partial class ForumRoleForumActionRightRelations + { + /// CTor + public ForumRoleForumActionRightRelations() + { + } + + /// Gets all relations of the ForumRoleForumActionRightEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.ActionRightEntityUsingActionRightID); + toReturn.Add(this.ForumEntityUsingForumID); + toReturn.Add(this.RoleEntityUsingRoleID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between ForumRoleForumActionRightEntity and ActionRightEntity over the m:1 relation they have, using the relation between the fields: + /// ForumRoleForumActionRight.ActionRightID - ActionRight.ActionRightID + /// + public virtual IEntityRelation ActionRightEntityUsingActionRightID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "ActionRight", false); + relation.AddEntityFieldPair(ActionRightFields.ActionRightID, ForumRoleForumActionRightFields.ActionRightID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ActionRightEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumRoleForumActionRightEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between ForumRoleForumActionRightEntity and ForumEntity over the m:1 relation they have, using the relation between the fields: + /// ForumRoleForumActionRight.ForumID - Forum.ForumID + /// + public virtual IEntityRelation ForumEntityUsingForumID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Forum", false); + relation.AddEntityFieldPair(ForumFields.ForumID, ForumRoleForumActionRightFields.ForumID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumRoleForumActionRightEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between ForumRoleForumActionRightEntity and RoleEntity over the m:1 relation they have, using the relation between the fields: + /// ForumRoleForumActionRight.RoleID - Role.RoleID + /// + public virtual IEntityRelation RoleEntityUsingRoleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Role", false); + relation.AddEntityFieldPair(RoleFields.RoleID, ForumRoleForumActionRightFields.RoleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumRoleForumActionRightEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/IPBanRelations.cs b/DAL/RelationClasses/IPBanRelations.cs new file mode 100644 index 0000000..aa75243 --- /dev/null +++ b/DAL/RelationClasses/IPBanRelations.cs @@ -0,0 +1,69 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: IPBan. + public partial class IPBanRelations + { + /// CTor + public IPBanRelations() + { + } + + /// Gets all relations of the IPBanEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.UserEntityUsingIPBanSetByUserID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between IPBanEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// IPBan.IPBanSetByUserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingIPBanSetByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "SetByUser", false); + relation.AddEntityFieldPair(UserFields.UserID, IPBanFields.IPBanSetByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("IPBanEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/MessageRelations.cs b/DAL/RelationClasses/MessageRelations.cs new file mode 100644 index 0000000..7d8848d --- /dev/null +++ b/DAL/RelationClasses/MessageRelations.cs @@ -0,0 +1,114 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: Message. + public partial class MessageRelations + { + /// CTor + public MessageRelations() + { + } + + /// Gets all relations of the MessageEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.AttachmentEntityUsingMessageID); + toReturn.Add(this.AuditDataMessageRelatedEntityUsingMessageID); + + toReturn.Add(this.ThreadEntityUsingThreadID); + toReturn.Add(this.UserEntityUsingPostedByUserID); + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between MessageEntity and AttachmentEntity over the 1:n relation they have, using the relation between the fields: + /// Message.MessageID - Attachment.MessageID + /// + public virtual IEntityRelation AttachmentEntityUsingMessageID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "Attachments" , true); + relation.AddEntityFieldPair(MessageFields.MessageID, AttachmentFields.MessageID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("MessageEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AttachmentEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between MessageEntity and AuditDataMessageRelatedEntity over the 1:n relation they have, using the relation between the fields: + /// Message.MessageID - AuditDataMessageRelated.MessageID + /// + public virtual IEntityRelation AuditDataMessageRelatedEntityUsingMessageID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "AuditDataMessageRelated" , true); + relation.AddEntityFieldPair(MessageFields.MessageID, AuditDataMessageRelatedFields.MessageID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("MessageEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataMessageRelatedEntity", false); + return relation; + } + } + + + /// Returns a new IEntityRelation object, between MessageEntity and ThreadEntity over the m:1 relation they have, using the relation between the fields: + /// Message.ThreadID - Thread.ThreadID + /// + public virtual IEntityRelation ThreadEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Thread", false); + relation.AddEntityFieldPair(ThreadFields.ThreadID, MessageFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("MessageEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between MessageEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// Message.PostedByUserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingPostedByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "PostedByUser", false); + relation.AddEntityFieldPair(UserFields.UserID, MessageFields.PostedByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("MessageEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/RoleAuditActionRelations.cs b/DAL/RelationClasses/RoleAuditActionRelations.cs new file mode 100644 index 0000000..c5e5470 --- /dev/null +++ b/DAL/RelationClasses/RoleAuditActionRelations.cs @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: RoleAuditAction. + public partial class RoleAuditActionRelations + { + /// CTor + public RoleAuditActionRelations() + { + } + + /// Gets all relations of the RoleAuditActionEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.AuditActionEntityUsingAuditActionID); + toReturn.Add(this.RoleEntityUsingRoleID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between RoleAuditActionEntity and AuditActionEntity over the m:1 relation they have, using the relation between the fields: + /// RoleAuditAction.AuditActionID - AuditAction.AuditActionID + /// + public virtual IEntityRelation AuditActionEntityUsingAuditActionID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "AuditAction", false); + relation.AddEntityFieldPair(AuditActionFields.AuditActionID, RoleAuditActionFields.AuditActionID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditActionEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleAuditActionEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between RoleAuditActionEntity and RoleEntity over the m:1 relation they have, using the relation between the fields: + /// RoleAuditAction.RoleID - Role.RoleID + /// + public virtual IEntityRelation RoleEntityUsingRoleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Role", false); + relation.AddEntityFieldPair(RoleFields.RoleID, RoleAuditActionFields.RoleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleAuditActionEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/RoleRelations.cs b/DAL/RelationClasses/RoleRelations.cs new file mode 100644 index 0000000..0e5f7e3 --- /dev/null +++ b/DAL/RelationClasses/RoleRelations.cs @@ -0,0 +1,149 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: Role. + public partial class RoleRelations + { + /// CTor + public RoleRelations() + { + } + + /// Gets all relations of the RoleEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.ForumRoleForumActionRightEntityUsingRoleID); + toReturn.Add(this.RoleAuditActionEntityUsingRoleID); + toReturn.Add(this.RoleSystemActionRightEntityUsingRoleID); + toReturn.Add(this.RoleUserEntityUsingRoleID); + toReturn.Add(this.SystemDataEntityUsingAnonymousRole); + toReturn.Add(this.SystemDataEntityUsingDefaultRoleNewUser); + + + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between RoleEntity and ForumRoleForumActionRightEntity over the 1:n relation they have, using the relation between the fields: + /// Role.RoleID - ForumRoleForumActionRight.RoleID + /// + public virtual IEntityRelation ForumRoleForumActionRightEntityUsingRoleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "ForumRoleForumActionRights" , true); + relation.AddEntityFieldPair(RoleFields.RoleID, ForumRoleForumActionRightFields.RoleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumRoleForumActionRightEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between RoleEntity and RoleAuditActionEntity over the 1:n relation they have, using the relation between the fields: + /// Role.RoleID - RoleAuditAction.RoleID + /// + public virtual IEntityRelation RoleAuditActionEntityUsingRoleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "RoleAuditAction" , true); + relation.AddEntityFieldPair(RoleFields.RoleID, RoleAuditActionFields.RoleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleAuditActionEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between RoleEntity and RoleSystemActionRightEntity over the 1:n relation they have, using the relation between the fields: + /// Role.RoleID - RoleSystemActionRight.RoleID + /// + public virtual IEntityRelation RoleSystemActionRightEntityUsingRoleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "RoleSystemActionRights" , true); + relation.AddEntityFieldPair(RoleFields.RoleID, RoleSystemActionRightFields.RoleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleSystemActionRightEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between RoleEntity and RoleUserEntity over the 1:n relation they have, using the relation between the fields: + /// Role.RoleID - RoleUser.RoleID + /// + public virtual IEntityRelation RoleUserEntityUsingRoleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "RoleUser" , true); + relation.AddEntityFieldPair(RoleFields.RoleID, RoleUserFields.RoleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleUserEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between RoleEntity and SystemDataEntity over the 1:n relation they have, using the relation between the fields: + /// Role.RoleID - SystemData.AnonymousRole + /// + public virtual IEntityRelation SystemDataEntityUsingAnonymousRole + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "SystemDataAnonymousRole" , true); + relation.AddEntityFieldPair(RoleFields.RoleID, SystemDataFields.AnonymousRole); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SystemDataEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between RoleEntity and SystemDataEntity over the 1:n relation they have, using the relation between the fields: + /// Role.RoleID - SystemData.DefaultRoleNewUser + /// + public virtual IEntityRelation SystemDataEntityUsingDefaultRoleNewUser + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "SystemDataDefaultRoleNewUser" , true); + relation.AddEntityFieldPair(RoleFields.RoleID, SystemDataFields.DefaultRoleNewUser); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SystemDataEntity", false); + return relation; + } + } + + + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/RoleSystemActionRightRelations.cs b/DAL/RelationClasses/RoleSystemActionRightRelations.cs new file mode 100644 index 0000000..f4ecb0f --- /dev/null +++ b/DAL/RelationClasses/RoleSystemActionRightRelations.cs @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: RoleSystemActionRight. + public partial class RoleSystemActionRightRelations + { + /// CTor + public RoleSystemActionRightRelations() + { + } + + /// Gets all relations of the RoleSystemActionRightEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.ActionRightEntityUsingActionRightID); + toReturn.Add(this.RoleEntityUsingRoleID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between RoleSystemActionRightEntity and ActionRightEntity over the m:1 relation they have, using the relation between the fields: + /// RoleSystemActionRight.ActionRightID - ActionRight.ActionRightID + /// + public virtual IEntityRelation ActionRightEntityUsingActionRightID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "ActionRight", false); + relation.AddEntityFieldPair(ActionRightFields.ActionRightID, RoleSystemActionRightFields.ActionRightID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ActionRightEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleSystemActionRightEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between RoleSystemActionRightEntity and RoleEntity over the m:1 relation they have, using the relation between the fields: + /// RoleSystemActionRight.RoleID - Role.RoleID + /// + public virtual IEntityRelation RoleEntityUsingRoleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Role", false); + relation.AddEntityFieldPair(RoleFields.RoleID, RoleSystemActionRightFields.RoleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleSystemActionRightEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/RoleUserRelations.cs b/DAL/RelationClasses/RoleUserRelations.cs new file mode 100644 index 0000000..5425bf6 --- /dev/null +++ b/DAL/RelationClasses/RoleUserRelations.cs @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: RoleUser. + public partial class RoleUserRelations + { + /// CTor + public RoleUserRelations() + { + } + + /// Gets all relations of the RoleUserEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.RoleEntityUsingRoleID); + toReturn.Add(this.UserEntityUsingUserID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between RoleUserEntity and RoleEntity over the m:1 relation they have, using the relation between the fields: + /// RoleUser.RoleID - Role.RoleID + /// + public virtual IEntityRelation RoleEntityUsingRoleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Role", false); + relation.AddEntityFieldPair(RoleFields.RoleID, RoleUserFields.RoleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleUserEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between RoleUserEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// RoleUser.UserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "User", false); + relation.AddEntityFieldPair(UserFields.UserID, RoleUserFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleUserEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/SectionRelations.cs b/DAL/RelationClasses/SectionRelations.cs new file mode 100644 index 0000000..448dad9 --- /dev/null +++ b/DAL/RelationClasses/SectionRelations.cs @@ -0,0 +1,69 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: Section. + public partial class SectionRelations + { + /// CTor + public SectionRelations() + { + } + + /// Gets all relations of the SectionEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.ForumEntityUsingSectionID); + + + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between SectionEntity and ForumEntity over the 1:n relation they have, using the relation between the fields: + /// Section.SectionID - Forum.SectionID + /// + public virtual IEntityRelation ForumEntityUsingSectionID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "Forums" , true); + relation.AddEntityFieldPair(SectionFields.SectionID, ForumFields.SectionID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SectionEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumEntity", false); + return relation; + } + } + + + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/SupportQueueRelations.cs b/DAL/RelationClasses/SupportQueueRelations.cs new file mode 100644 index 0000000..56c4fb8 --- /dev/null +++ b/DAL/RelationClasses/SupportQueueRelations.cs @@ -0,0 +1,85 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: SupportQueue. + public partial class SupportQueueRelations + { + /// CTor + public SupportQueueRelations() + { + } + + /// Gets all relations of the SupportQueueEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.ForumEntityUsingDefaultSupportQueueID); + toReturn.Add(this.SupportQueueThreadEntityUsingQueueID); + + + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between SupportQueueEntity and ForumEntity over the 1:n relation they have, using the relation between the fields: + /// SupportQueue.QueueID - Forum.DefaultSupportQueueID + /// + public virtual IEntityRelation ForumEntityUsingDefaultSupportQueueID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "DefaultForForums" , true); + relation.AddEntityFieldPair(SupportQueueFields.QueueID, ForumFields.DefaultSupportQueueID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between SupportQueueEntity and SupportQueueThreadEntity over the 1:n relation they have, using the relation between the fields: + /// SupportQueue.QueueID - SupportQueueThread.QueueID + /// + public virtual IEntityRelation SupportQueueThreadEntityUsingQueueID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "SupportQueueThreads" , true); + relation.AddEntityFieldPair(SupportQueueFields.QueueID, SupportQueueThreadFields.QueueID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueThreadEntity", false); + return relation; + } + } + + + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/SupportQueueThreadRelations.cs b/DAL/RelationClasses/SupportQueueThreadRelations.cs new file mode 100644 index 0000000..57b7d61 --- /dev/null +++ b/DAL/RelationClasses/SupportQueueThreadRelations.cs @@ -0,0 +1,117 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: SupportQueueThread. + public partial class SupportQueueThreadRelations + { + /// CTor + public SupportQueueThreadRelations() + { + } + + /// Gets all relations of the SupportQueueThreadEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + toReturn.Add(this.ThreadEntityUsingThreadID); + toReturn.Add(this.SupportQueueEntityUsingQueueID); + toReturn.Add(this.UserEntityUsingClaimedByUserID); + toReturn.Add(this.UserEntityUsingPlacedInQueueByUserID); + return toReturn; + } + + #region Class Property Declarations + + + /// Returns a new IEntityRelation object, between SupportQueueThreadEntity and ThreadEntity over the 1:1 relation they have, using the relation between the fields: + /// SupportQueueThread.ThreadID - Thread.ThreadID + /// + public virtual IEntityRelation ThreadEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToOne, "Thread", false); + + + + + relation.AddEntityFieldPair(ThreadFields.ThreadID, SupportQueueThreadFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueThreadEntity", true); + return relation; + } + } + + /// Returns a new IEntityRelation object, between SupportQueueThreadEntity and SupportQueueEntity over the m:1 relation they have, using the relation between the fields: + /// SupportQueueThread.QueueID - SupportQueue.QueueID + /// + public virtual IEntityRelation SupportQueueEntityUsingQueueID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "SupportQueue", false); + relation.AddEntityFieldPair(SupportQueueFields.QueueID, SupportQueueThreadFields.QueueID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueThreadEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between SupportQueueThreadEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// SupportQueueThread.ClaimedByUserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingClaimedByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "ClaimedByUser", false); + relation.AddEntityFieldPair(UserFields.UserID, SupportQueueThreadFields.ClaimedByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueThreadEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between SupportQueueThreadEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// SupportQueueThread.PlacedInQueueByUserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingPlacedInQueueByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "PlacedInQueueByUser", false); + relation.AddEntityFieldPair(UserFields.UserID, SupportQueueThreadFields.PlacedInQueueByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueThreadEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/SystemDataRelations.cs b/DAL/RelationClasses/SystemDataRelations.cs new file mode 100644 index 0000000..8e39c01 --- /dev/null +++ b/DAL/RelationClasses/SystemDataRelations.cs @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: SystemData. + public partial class SystemDataRelations + { + /// CTor + public SystemDataRelations() + { + } + + /// Gets all relations of the SystemDataEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.RoleEntityUsingAnonymousRole); + toReturn.Add(this.RoleEntityUsingDefaultRoleNewUser); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between SystemDataEntity and RoleEntity over the m:1 relation they have, using the relation between the fields: + /// SystemData.AnonymousRole - Role.RoleID + /// + public virtual IEntityRelation RoleEntityUsingAnonymousRole + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "RoleForAnonymous", false); + relation.AddEntityFieldPair(RoleFields.RoleID, SystemDataFields.AnonymousRole); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SystemDataEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between SystemDataEntity and RoleEntity over the m:1 relation they have, using the relation between the fields: + /// SystemData.DefaultRoleNewUser - Role.RoleID + /// + public virtual IEntityRelation RoleEntityUsingDefaultRoleNewUser + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "RoleForNewUser", false); + relation.AddEntityFieldPair(RoleFields.RoleID, SystemDataFields.DefaultRoleNewUser); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SystemDataEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/ThreadRelations.cs b/DAL/RelationClasses/ThreadRelations.cs new file mode 100644 index 0000000..c292b3c --- /dev/null +++ b/DAL/RelationClasses/ThreadRelations.cs @@ -0,0 +1,164 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: Thread. + public partial class ThreadRelations + { + /// CTor + public ThreadRelations() + { + } + + /// Gets all relations of the ThreadEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.AuditDataThreadRelatedEntityUsingThreadID); + toReturn.Add(this.BookmarkEntityUsingThreadID); + toReturn.Add(this.MessageEntityUsingThreadID); + toReturn.Add(this.ThreadSubscriptionEntityUsingThreadID); + toReturn.Add(this.SupportQueueThreadEntityUsingThreadID); + toReturn.Add(this.ForumEntityUsingForumID); + toReturn.Add(this.UserEntityUsingStartedByUserID); + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between ThreadEntity and AuditDataThreadRelatedEntity over the 1:n relation they have, using the relation between the fields: + /// Thread.ThreadID - AuditDataThreadRelated.ThreadID + /// + public virtual IEntityRelation AuditDataThreadRelatedEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "AuditDataThreadRelated" , true); + relation.AddEntityFieldPair(ThreadFields.ThreadID, AuditDataThreadRelatedFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataThreadRelatedEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between ThreadEntity and BookmarkEntity over the 1:n relation they have, using the relation between the fields: + /// Thread.ThreadID - Bookmark.ThreadID + /// + public virtual IEntityRelation BookmarkEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "PresentInBookmarks" , true); + relation.AddEntityFieldPair(ThreadFields.ThreadID, BookmarkFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("BookmarkEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between ThreadEntity and MessageEntity over the 1:n relation they have, using the relation between the fields: + /// Thread.ThreadID - Message.ThreadID + /// + public virtual IEntityRelation MessageEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "Messages" , true); + relation.AddEntityFieldPair(ThreadFields.ThreadID, MessageFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("MessageEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between ThreadEntity and ThreadSubscriptionEntity over the 1:n relation they have, using the relation between the fields: + /// Thread.ThreadID - ThreadSubscription.ThreadID + /// + public virtual IEntityRelation ThreadSubscriptionEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "ThreadSubscription" , true); + relation.AddEntityFieldPair(ThreadFields.ThreadID, ThreadSubscriptionFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadSubscriptionEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between ThreadEntity and SupportQueueThreadEntity over the 1:1 relation they have, using the relation between the fields: + /// Thread.ThreadID - SupportQueueThread.ThreadID + /// + public virtual IEntityRelation SupportQueueThreadEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToOne, "SupportQueueThread", true); + + + relation.AddEntityFieldPair(ThreadFields.ThreadID, SupportQueueThreadFields.ThreadID); + + + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueThreadEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between ThreadEntity and ForumEntity over the m:1 relation they have, using the relation between the fields: + /// Thread.ForumID - Forum.ForumID + /// + public virtual IEntityRelation ForumEntityUsingForumID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Forum", false); + relation.AddEntityFieldPair(ForumFields.ForumID, ThreadFields.ForumID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ForumEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between ThreadEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// Thread.StartedByUserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingStartedByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "UserWhoStartedThread", false); + relation.AddEntityFieldPair(UserFields.UserID, ThreadFields.StartedByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/ThreadSubscriptionRelations.cs b/DAL/RelationClasses/ThreadSubscriptionRelations.cs new file mode 100644 index 0000000..a2eb0b8 --- /dev/null +++ b/DAL/RelationClasses/ThreadSubscriptionRelations.cs @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: ThreadSubscription. + public partial class ThreadSubscriptionRelations + { + /// CTor + public ThreadSubscriptionRelations() + { + } + + /// Gets all relations of the ThreadSubscriptionEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + + + toReturn.Add(this.ThreadEntityUsingThreadID); + toReturn.Add(this.UserEntityUsingUserID); + return toReturn; + } + + #region Class Property Declarations + + + + /// Returns a new IEntityRelation object, between ThreadSubscriptionEntity and ThreadEntity over the m:1 relation they have, using the relation between the fields: + /// ThreadSubscription.ThreadID - Thread.ThreadID + /// + public virtual IEntityRelation ThreadEntityUsingThreadID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "Thread", false); + relation.AddEntityFieldPair(ThreadFields.ThreadID, ThreadSubscriptionFields.ThreadID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadSubscriptionEntity", true); + return relation; + } + } + /// Returns a new IEntityRelation object, between ThreadSubscriptionEntity and UserEntity over the m:1 relation they have, using the relation between the fields: + /// ThreadSubscription.UserID - User.UserID + /// + public virtual IEntityRelation UserEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "User", false); + relation.AddEntityFieldPair(UserFields.UserID, ThreadSubscriptionFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadSubscriptionEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/UserRelations.cs b/DAL/RelationClasses/UserRelations.cs new file mode 100644 index 0000000..6948100 --- /dev/null +++ b/DAL/RelationClasses/UserRelations.cs @@ -0,0 +1,211 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: User. + public partial class UserRelations + { + /// CTor + public UserRelations() + { + } + + /// Gets all relations of the UserEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.AuditDataCoreEntityUsingUserID); + toReturn.Add(this.BookmarkEntityUsingUserID); + toReturn.Add(this.IPBanEntityUsingIPBanSetByUserID); + toReturn.Add(this.MessageEntityUsingPostedByUserID); + toReturn.Add(this.RoleUserEntityUsingUserID); + toReturn.Add(this.SupportQueueThreadEntityUsingClaimedByUserID); + toReturn.Add(this.SupportQueueThreadEntityUsingPlacedInQueueByUserID); + toReturn.Add(this.ThreadEntityUsingStartedByUserID); + toReturn.Add(this.ThreadSubscriptionEntityUsingUserID); + + toReturn.Add(this.UserTitleEntityUsingUserTitleID); + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between UserEntity and AuditDataCoreEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - AuditDataCore.UserID + /// + public virtual IEntityRelation AuditDataCoreEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "LoggedAudits" , true); + relation.AddEntityFieldPair(UserFields.UserID, AuditDataCoreFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("AuditDataCoreEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between UserEntity and BookmarkEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - Bookmark.UserID + /// + public virtual IEntityRelation BookmarkEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "Bookmarks" , true); + relation.AddEntityFieldPair(UserFields.UserID, BookmarkFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("BookmarkEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between UserEntity and IPBanEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - IPBan.IPBanSetByUserID + /// + public virtual IEntityRelation IPBanEntityUsingIPBanSetByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "IPBansSet" , true); + relation.AddEntityFieldPair(UserFields.UserID, IPBanFields.IPBanSetByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("IPBanEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between UserEntity and MessageEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - Message.PostedByUserID + /// + public virtual IEntityRelation MessageEntityUsingPostedByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "PostedMessages" , true); + relation.AddEntityFieldPair(UserFields.UserID, MessageFields.PostedByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("MessageEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between UserEntity and RoleUserEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - RoleUser.UserID + /// + public virtual IEntityRelation RoleUserEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "RoleUser" , true); + relation.AddEntityFieldPair(UserFields.UserID, RoleUserFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("RoleUserEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between UserEntity and SupportQueueThreadEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - SupportQueueThread.ClaimedByUserID + /// + public virtual IEntityRelation SupportQueueThreadEntityUsingClaimedByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "SupportQueueThreadsClaimed" , true); + relation.AddEntityFieldPair(UserFields.UserID, SupportQueueThreadFields.ClaimedByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueThreadEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between UserEntity and SupportQueueThreadEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - SupportQueueThread.PlacedInQueueByUserID + /// + public virtual IEntityRelation SupportQueueThreadEntityUsingPlacedInQueueByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "SupportQueueThreadsPlaced" , true); + relation.AddEntityFieldPair(UserFields.UserID, SupportQueueThreadFields.PlacedInQueueByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("SupportQueueThreadEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between UserEntity and ThreadEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - Thread.StartedByUserID + /// + public virtual IEntityRelation ThreadEntityUsingStartedByUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "StartedThreads" , true); + relation.AddEntityFieldPair(UserFields.UserID, ThreadFields.StartedByUserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadEntity", false); + return relation; + } + } + + /// Returns a new IEntityRelation object, between UserEntity and ThreadSubscriptionEntity over the 1:n relation they have, using the relation between the fields: + /// User.UserID - ThreadSubscription.UserID + /// + public virtual IEntityRelation ThreadSubscriptionEntityUsingUserID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "ThreadSubscription" , true); + relation.AddEntityFieldPair(UserFields.UserID, ThreadSubscriptionFields.UserID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("ThreadSubscriptionEntity", false); + return relation; + } + } + + + /// Returns a new IEntityRelation object, between UserEntity and UserTitleEntity over the m:1 relation they have, using the relation between the fields: + /// User.UserTitleID - UserTitle.UserTitleID + /// + public virtual IEntityRelation UserTitleEntityUsingUserTitleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.ManyToOne, "UserTitle", false); + relation.AddEntityFieldPair(UserTitleFields.UserTitleID, UserFields.UserTitleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserTitleEntity", false); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", true); + return relation; + } + } + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/RelationClasses/UserTitleRelations.cs b/DAL/RelationClasses/UserTitleRelations.cs new file mode 100644 index 0000000..6aefa74 --- /dev/null +++ b/DAL/RelationClasses/UserTitleRelations.cs @@ -0,0 +1,69 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Collections; +using System.Collections.Generic; +using SD.HnD.DAL; +using SD.HnD.DAL.FactoryClasses; +using SD.HnD.DAL.HelperClasses; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.RelationClasses +{ + /// Implements the static Relations variant for the entity: UserTitle. + public partial class UserTitleRelations + { + /// CTor + public UserTitleRelations() + { + } + + /// Gets all relations of the UserTitleEntity as a list of IEntityRelation objects. + /// a list of IEntityRelation objects + public virtual List GetAllRelations() + { + List toReturn = new List(); + toReturn.Add(this.UserEntityUsingUserTitleID); + + + return toReturn; + } + + #region Class Property Declarations + + /// Returns a new IEntityRelation object, between UserTitleEntity and UserEntity over the 1:n relation they have, using the relation between the fields: + /// UserTitle.UserTitleID - User.UserTitleID + /// + public virtual IEntityRelation UserEntityUsingUserTitleID + { + get + { + IEntityRelation relation = new EntityRelation(SD.LLBLGen.Pro.ORMSupportClasses.RelationType.OneToMany, "Users" , true); + relation.AddEntityFieldPair(UserTitleFields.UserTitleID, UserFields.UserTitleID); + relation.InheritanceInfoPkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserTitleEntity", true); + relation.InheritanceInfoFkSideEntity = InheritanceInfoProviderSingleton.GetInstance().GetInheritanceInfo("UserEntity", false); + return relation; + } + } + + + + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSubTypeRelation(string subTypeEntityName) { return null; } + /// stub, not used in this entity, only for TargetPerEntity entities. + public virtual IEntityRelation GetSuperTypeRelation() { return null;} + + #endregion + + #region Included Code + + #endregion + } +} diff --git a/DAL/SD.HnD.DAL.csproj b/DAL/SD.HnD.DAL.csproj new file mode 100644 index 0000000..c700f28 --- /dev/null +++ b/DAL/SD.HnD.DAL.csproj @@ -0,0 +1,569 @@ + + + + Local + 8.0.50727 + 2.0 + {43C8451A-A377-4589-BF7D-73BE386E7B4D} + Debug + AnyCPU + + + + + SD.HnD.DAL + + + JScript + Grid + IE50 + false + Library + SD.HnD.DAL + OnBuildSuccess + + + + + + + v3.5 + 2.0 + http://localhost/SD.HnD.DAL/ + true + Web + true + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + true + false + true + + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + AllRules.ruleset + + + bin\Release\ + false + 285212672 + false + + + TRACE + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + AllRules.ruleset + + + + False + ..\RuntimeLibraries\SD.LLBLGen.Pro.DQE.SqlServer.NET20.dll + + + False + ..\RuntimeLibraries\SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll + + + System + + + System.Data + + + System.EnterpriseServices + + + System.XML + + + + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + LLBLGen Pro + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + + + \ No newline at end of file diff --git a/DAL/StoredProcedureCallerClasses/ActionProcedures.cs b/DAL/StoredProcedureCallerClasses/ActionProcedures.cs new file mode 100644 index 0000000..cec6cf0 --- /dev/null +++ b/DAL/StoredProcedureCallerClasses/ActionProcedures.cs @@ -0,0 +1,38 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SqlServerSpecific.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.SqlClient; + +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.StoredProcedureCallerClasses +{ + /// + /// Class which contains the static logic to execute action stored procedures in the database. + /// + public partial class ActionProcedures + { + /// + /// private CTor so no instance can be created. + /// + private ActionProcedures() + { + } + + + + #region Included Code + + #endregion + } +} diff --git a/DAL/StoredProcedureCallerClasses/RetrievalProcedures.cs b/DAL/StoredProcedureCallerClasses/RetrievalProcedures.cs new file mode 100644 index 0000000..a7d2224 --- /dev/null +++ b/DAL/StoredProcedureCallerClasses/RetrievalProcedures.cs @@ -0,0 +1,38 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SqlServerSpecific.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.Data; +using System.Data.SqlClient; + +using SD.HnD.DAL.HelperClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.StoredProcedureCallerClasses +{ + /// + /// Class which contains the static logic to execute retrieval stored procedures in the database. + /// + public partial class RetrievalProcedures + { + /// + /// private CTor so no instance can be created. + /// + private RetrievalProcedures() + { + } + + + + #region Included Code + + #endregion + } +} diff --git a/DAL/TypedListClasses/ForumMessagesTypedList.cs b/DAL/TypedListClasses/ForumMessagesTypedList.cs new file mode 100644 index 0000000..f55c343 --- /dev/null +++ b/DAL/TypedListClasses/ForumMessagesTypedList.cs @@ -0,0 +1,975 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Data; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.TypedListClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Typed datatable for the list 'ForumMessages'.

+ ///
+ /// + /// It embeds a fill method which accepts a filter. + /// The code doesn't support any changing of data. Users who do that are on their own. + /// It also doesn't support any event throwing. This list should be used as a base for readonly databinding + /// or dataview construction. + /// +#if !CF + [Serializable, System.ComponentModel.DesignerCategory("Code")] + [ToolboxItem(true)] + [DesignTimeVisible(true)] +#endif + public partial class ForumMessagesTypedList : TypedListBase, ITypedListLgp + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfacesList + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private DataColumn _columnMessageID; + private DataColumn _columnPostingDate; + private DataColumn _columnMessageTextAsHTML; + private DataColumn _columnThreadID; + private DataColumn _columnSubject; + private DataColumn _columnEmailAddress; + private DataColumn _columnEmailAddressIsPublic; + private DataColumn _columnNickName; + private DataColumn _columnMessageText; + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalMembers + // __LLBLGENPRO_USER_CODE_REGION_END + private static Hashtable _customProperties; + private static Hashtable _fieldsCustomProperties; + #endregion + + #region Class Constants + /// The amount of fields in the resultset. + private const int AmountOfFields = 9; + #endregion + + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this + /// class or derived classes is constructed. + static ForumMessagesTypedList() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public ForumMessagesTypedList():base("ForumMessages") + { + InitClass(false); + } + + + /// CTor + /// The flag to signal the collection what kind of join statements to generate in the + /// query statement. Weak relationships are relationships which are optional, for example a + /// customer with no orders is possible, because the relationship between customer and order is based on a field in order. + /// When this property is set to true (default: false), weak relationships will result in LEFT JOIN statements. When + /// set to false (which is the default), INNER JOIN statements are used. + /// + public ForumMessagesTypedList(bool obeyWeakRelations):base("ForumMessages") + { + InitClass(obeyWeakRelations); + } + +#if !CF + /// Protected constructor for deserialization. + /// + /// + protected ForumMessagesTypedList(SerializationInfo info, StreamingContext context):base(info, context) + { + InitMembers(); + } +#endif + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will use no sort filter, no select filter, will allow duplicate rows and will not limit the amount of rows returned + /// true if fill succeeded, false otherwise + public bool Fill() + { + return Fill(0, null, true, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will not use a filter, will allow duplicate rows. + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, true, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will not use a filter. + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// true if fill succeeded, false otherwise + public virtual bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, transactionToUse, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// GroupByCollection with fields to group by on. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, + IGroupByCollection groupByClause) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, transactionToUse, groupByClause, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// GroupByCollection with fields to group by on. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if fill succeeded, false otherwise + public virtual bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, + IGroupByCollection groupByClause, int pageNumber, int pageSize) + { + IEntityFields fieldsInResultset = BuildResultset(); + IRelationCollection relations = BuildRelationSet(); + + TypedListDAO dao = DAOFactory.CreateTypedListDAO(); + return dao.GetMultiAsDataTable(fieldsInResultset, this, maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, allowDuplicates, groupByClause, transactionToUse, pageNumber, pageSize); + } + + + /// Gets the amount of rows in the database for this typed list, not skipping duplicates + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount() + { + return GetDbCount(true, null, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates) + { + return GetDbCount(allowDuplicates, null, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates, IPredicateExpression filter) + { + return GetDbCount(allowDuplicates, filter, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// The relations for the filter to apply + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates, IPredicateExpression filter, IRelationCollection relations) + { + return GetDbCount(allowDuplicates, filter, relations, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// The relations for the filter to apply + /// group by clause to embed in the query + /// the number of rows in the set defined by the passed in query elements + public virtual int GetDbCount(bool allowDuplicates, IPredicateExpression filter, IRelationCollection relations, GroupByCollection groupByClause) + { + IEntityFields fieldsInResultset = BuildResultset(); + IRelationCollection relationsToUse = BuildRelationSet(); + if(relations!=null) + { + for (int i = 0; i < relations.Count; i++) + { + relationsToUse.Add(relations[i]); + } + } + + TypedListDAO dao = DAOFactory.CreateTypedListDAO(); + return dao.GetDbCount(fieldsInResultset, null, filter, relationsToUse, groupByClause, allowDuplicates); + } + + + /// Builds the relation set for this typed list. + /// ready to use relation set + public virtual IRelationCollection BuildRelationSet() + { + IRelationCollection toReturn = new RelationCollection(); + toReturn.ObeyWeakRelations = base.ObeyWeakRelations; + toReturn.Add(MessageEntity.Relations.ThreadEntityUsingThreadID, "", "", JoinHint.None); + toReturn.Add(ThreadEntity.Relations.ForumEntityUsingForumID, "", "", JoinHint.None); + toReturn.Add(MessageEntity.Relations.UserEntityUsingPostedByUserID, "", "", JoinHint.None); + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalRelations + // __LLBLGENPRO_USER_CODE_REGION_END + OnRelationSetBuilt(toReturn); + return toReturn; + } + + + /// Builds the resultset fields. + /// ready to use resultset + public virtual IEntityFields BuildResultset() + { + ResultsetFields toReturn = new ResultsetFields(AmountOfFields); + toReturn.DefineField(MessageFields.MessageID, 0, "MessageID", "", AggregateFunction.None); + toReturn.DefineField(MessageFields.PostingDate, 1, "PostingDate", "", AggregateFunction.None); + toReturn.DefineField(MessageFields.MessageTextAsHTML, 2, "MessageTextAsHTML", "", AggregateFunction.None); + toReturn.DefineField(MessageFields.ThreadID, 3, "ThreadID", "", AggregateFunction.None); + toReturn.DefineField(ThreadFields.Subject, 4, "Subject", "", AggregateFunction.None); + toReturn.DefineField(UserFields.EmailAddress, 5, "EmailAddress", "", AggregateFunction.None); + toReturn.DefineField(UserFields.EmailAddressIsPublic, 6, "EmailAddressIsPublic", "", AggregateFunction.None); + toReturn.DefineField(UserFields.NickName, 7, "NickName", "", AggregateFunction.None); + toReturn.DefineField(MessageFields.MessageText, 8, "MessageText", "", AggregateFunction.None); + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalFields + // be sure to call toReturn.Expand(number of new fields) first. + // __LLBLGENPRO_USER_CODE_REGION_END + OnResultsetBuilt(toReturn); + return toReturn; + } + + + /// Gets an array of all ForumMessagesRow objects. + /// Array with ForumMessagesRow objects + public new ForumMessagesRow[] Select() + { + return (ForumMessagesRow[])base.Select(); + } + + + /// Gets an array of all ForumMessagesRow objects that match the filter criteria in order of primary key (or lacking one, order of addition.) + /// The criteria to use to filter the rows. + /// Array with ForumMessagesRow objects + public new ForumMessagesRow[] Select(string filterExpression) + { + return (ForumMessagesRow[])base.Select(filterExpression); + } + + + /// Gets an array of all ForumMessagesRow objects that match the filter criteria, in the specified sort order + /// The filter expression. + /// A string specifying the column and sort direction. + /// Array with ForumMessagesRow objects + public new ForumMessagesRow[] Select(string filterExpression, string sort) + { + return (ForumMessagesRow[])base.Select(filterExpression, sort); + } + + + /// Gets an array of all ForumMessagesRow objects that match the filter criteria, in the specified sort order that match the specified state + /// The filter expression. + /// A string specifying the column and sort direction. + /// One of the values. + /// Array with ForumMessagesRow objects + public new ForumMessagesRow[] Select(string filterExpression, string sort, DataViewRowState recordStates) + { + return (ForumMessagesRow[])base.Select(filterExpression, sort, recordStates); + } + + + /// Creates a new typed row during the build of the datatable during a Fill session by a dataadapter. + /// supplied row builder to pass to the typed row + /// the new typed datarow + protected override DataRow NewRowFromBuilder(DataRowBuilder rowBuilder) + { + return new ForumMessagesRow(rowBuilder); + } + + + /// Initializes the hashtables for the typed list type and typed list field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Hashtable(); + _fieldsCustomProperties = new Hashtable(); + + Hashtable fieldHashtable = null; + + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("MessageID", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("PostingDate", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("MessageTextAsHTML", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("Subject", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("EmailAddress", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("EmailAddressIsPublic", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("NickName", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("MessageText", fieldHashtable); + } + + + /// Initialize the datastructures. + /// flag for the internal used relations object + protected override void InitClass(bool obeyWeakRelations) + { + + _columnMessageID = new DataColumn("MessageID", typeof(System.Int32), null, MappingType.Element); + _columnMessageID.ReadOnly = true; + _columnMessageID.Caption = @"MessageID"; + this.Columns.Add(_columnMessageID); + + _columnPostingDate = new DataColumn("PostingDate", typeof(System.DateTime), null, MappingType.Element); + _columnPostingDate.ReadOnly = true; + _columnPostingDate.Caption = @"PostingDate"; + this.Columns.Add(_columnPostingDate); + + _columnMessageTextAsHTML = new DataColumn("MessageTextAsHTML", typeof(System.String), null, MappingType.Element); + _columnMessageTextAsHTML.ReadOnly = true; + _columnMessageTextAsHTML.Caption = @"MessageTextAsHTML"; + this.Columns.Add(_columnMessageTextAsHTML); + + _columnThreadID = new DataColumn("ThreadID", typeof(System.Int32), null, MappingType.Element); + _columnThreadID.ReadOnly = true; + _columnThreadID.Caption = @"ThreadID"; + this.Columns.Add(_columnThreadID); + + _columnSubject = new DataColumn("Subject", typeof(System.String), null, MappingType.Element); + _columnSubject.ReadOnly = true; + _columnSubject.Caption = @"Subject"; + this.Columns.Add(_columnSubject); + + _columnEmailAddress = new DataColumn("EmailAddress", typeof(System.String), null, MappingType.Element); + _columnEmailAddress.ReadOnly = true; + _columnEmailAddress.Caption = @"EmailAddress"; + this.Columns.Add(_columnEmailAddress); + + _columnEmailAddressIsPublic = new DataColumn("EmailAddressIsPublic", typeof(System.Boolean), null, MappingType.Element); + _columnEmailAddressIsPublic.ReadOnly = true; + _columnEmailAddressIsPublic.Caption = @"EmailAddressIsPublic"; + this.Columns.Add(_columnEmailAddressIsPublic); + + _columnNickName = new DataColumn("NickName", typeof(System.String), null, MappingType.Element); + _columnNickName.ReadOnly = true; + _columnNickName.Caption = @"NickName"; + this.Columns.Add(_columnNickName); + + _columnMessageText = new DataColumn("MessageText", typeof(System.String), null, MappingType.Element); + _columnMessageText.ReadOnly = true; + _columnMessageText.Caption = @"MessageText"; + this.Columns.Add(_columnMessageText); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClass + // __LLBLGENPRO_USER_CODE_REGION_END + base.ObeyWeakRelations = obeyWeakRelations; + OnInitialized(); + } + + + /// Initializes the members, after a clone action. + private void InitMembers() + { + _columnMessageID = this.Columns["MessageID"]; + _columnPostingDate = this.Columns["PostingDate"]; + _columnMessageTextAsHTML = this.Columns["MessageTextAsHTML"]; + _columnThreadID = this.Columns["ThreadID"]; + _columnSubject = this.Columns["Subject"]; + _columnEmailAddress = this.Columns["EmailAddress"]; + _columnEmailAddressIsPublic = this.Columns["EmailAddressIsPublic"]; + _columnNickName = this.Columns["NickName"]; + _columnMessageText = this.Columns["MessageText"]; + + // __LLBLGENPRO_USER_CODE_REGION_START InitMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitialized(); + } + + + /// Return the type of the typed datarow + /// returns the requested type + protected override Type GetRowType() + { + return typeof(ForumMessagesRow); + } + + + /// Clones this instance. + /// A clone of this instance + public override DataTable Clone() + { + ForumMessagesTypedList cloneToReturn = ((ForumMessagesTypedList)(base.Clone())); + cloneToReturn.InitMembers(); + return cloneToReturn; + } + +#if !CF + /// Creates a new instance of the DataTable class. + /// a new instance of a datatable with this schema. + protected override DataTable CreateInstance() + { + return new ForumMessagesTypedList(); + } +#endif + + #region Class Property Declarations + /// Returns the amount of rows in this typed list. + [System.ComponentModel.Browsable(false)] + public override int Count + { + get + { + return this.Rows.Count; + } + } + + /// The custom properties for this TypedList type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Hashtable CustomProperties + { + get { return _customProperties;} + } + + /// The custom properties for the type of this TypedList instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [System.ComponentModel.Browsable(false)] + public virtual Hashtable CustomPropertiesOfType + { + get { return ForumMessagesTypedList.CustomProperties;} + } + + /// The custom properties for the fields of this TypedList type. The returned Hashtable contains per fieldname a hashtable of name-value + /// pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Hashtable FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this TypedList instance. The returned Hashtable contains per fieldname a hashtable of name-value + /// pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [System.ComponentModel.Browsable(false)] + public virtual Hashtable FieldsCustomPropertiesOfType + { + get { return ForumMessagesTypedList.FieldsCustomProperties;} + } + + /// Indexer of this strong typed list + public ForumMessagesRow this[int index] + { + get + { + return ((ForumMessagesRow)(this.Rows[index])); + } + } + + + /// Returns the column object belonging to the TypedList field MessageID + internal DataColumn MessageIDColumn + { + get { return _columnMessageID; } + } + + /// Returns the column object belonging to the TypedList field PostingDate + internal DataColumn PostingDateColumn + { + get { return _columnPostingDate; } + } + + /// Returns the column object belonging to the TypedList field MessageTextAsHTML + internal DataColumn MessageTextAsHTMLColumn + { + get { return _columnMessageTextAsHTML; } + } + + /// Returns the column object belonging to the TypedList field ThreadID + internal DataColumn ThreadIDColumn + { + get { return _columnThreadID; } + } + + /// Returns the column object belonging to the TypedList field Subject + internal DataColumn SubjectColumn + { + get { return _columnSubject; } + } + + /// Returns the column object belonging to the TypedList field EmailAddress + internal DataColumn EmailAddressColumn + { + get { return _columnEmailAddress; } + } + + /// Returns the column object belonging to the TypedList field EmailAddressIsPublic + internal DataColumn EmailAddressIsPublicColumn + { + get { return _columnEmailAddressIsPublic; } + } + + /// Returns the column object belonging to the TypedList field NickName + internal DataColumn NickNameColumn + { + get { return _columnNickName; } + } + + /// Returns the column object belonging to the TypedList field MessageText + internal DataColumn MessageTextColumn + { + get { return _columnMessageText; } + } + + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalColumnProperties + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Custom TypedList code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomTypedListCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } + + + /// Typed datarow for the typed datatable ForumMessages + public partial class ForumMessagesRow : DataRow + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfacesRow + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private ForumMessagesTypedList _parent; + #endregion + + /// CTor + /// Row builder object to use when building this row + protected internal ForumMessagesRow(DataRowBuilder rowBuilder) : base(rowBuilder) + { + _parent = ((ForumMessagesTypedList)(this.Table)); + } + + + #region Class Property Declarations + + /// Gets / sets the value of the TypedList field MessageID

+ ///
+ /// Mapped on: Message.MessageID + public System.Int32 MessageID + { + get + { + if(IsMessageIDNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.MessageIDColumn]; + } + } + set + { + this[_parent.MessageIDColumn] = value; + } + } + + /// Returns true if the TypedList field MessageID is NULL, false otherwise. + public bool IsMessageIDNull() + { + return IsNull(_parent.MessageIDColumn); + } + + /// Sets the TypedList field MessageID to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetMessageIDNull() + { + this[_parent.MessageIDColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field PostingDate

+ ///
+ /// Mapped on: Message.PostingDate + public System.DateTime PostingDate + { + get + { + if(IsPostingDateNull()) + { + // return default value for this type. + return (System.DateTime)TypeDefaultValue.GetDefaultValue(typeof(System.DateTime)); + } + else + { + return (System.DateTime)this[_parent.PostingDateColumn]; + } + } + set + { + this[_parent.PostingDateColumn] = value; + } + } + + /// Returns true if the TypedList field PostingDate is NULL, false otherwise. + public bool IsPostingDateNull() + { + return IsNull(_parent.PostingDateColumn); + } + + /// Sets the TypedList field PostingDate to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetPostingDateNull() + { + this[_parent.PostingDateColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field MessageTextAsHTML

+ ///
+ /// Mapped on: Message.MessageTextAsHTML + public System.String MessageTextAsHTML + { + get + { + if(IsMessageTextAsHTMLNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.MessageTextAsHTMLColumn]; + } + } + set + { + this[_parent.MessageTextAsHTMLColumn] = value; + } + } + + /// Returns true if the TypedList field MessageTextAsHTML is NULL, false otherwise. + public bool IsMessageTextAsHTMLNull() + { + return IsNull(_parent.MessageTextAsHTMLColumn); + } + + /// Sets the TypedList field MessageTextAsHTML to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetMessageTextAsHTMLNull() + { + this[_parent.MessageTextAsHTMLColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field ThreadID

+ ///
+ /// Mapped on: Message.ThreadID + public System.Int32 ThreadID + { + get + { + if(IsThreadIDNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.ThreadIDColumn]; + } + } + set + { + this[_parent.ThreadIDColumn] = value; + } + } + + /// Returns true if the TypedList field ThreadID is NULL, false otherwise. + public bool IsThreadIDNull() + { + return IsNull(_parent.ThreadIDColumn); + } + + /// Sets the TypedList field ThreadID to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetThreadIDNull() + { + this[_parent.ThreadIDColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field Subject

+ ///
+ /// Mapped on: Thread.Subject + public System.String Subject + { + get + { + if(IsSubjectNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.SubjectColumn]; + } + } + set + { + this[_parent.SubjectColumn] = value; + } + } + + /// Returns true if the TypedList field Subject is NULL, false otherwise. + public bool IsSubjectNull() + { + return IsNull(_parent.SubjectColumn); + } + + /// Sets the TypedList field Subject to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetSubjectNull() + { + this[_parent.SubjectColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field EmailAddress

+ ///
+ /// Mapped on: User.EmailAddress + public System.String EmailAddress + { + get + { + if(IsEmailAddressNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.EmailAddressColumn]; + } + } + set + { + this[_parent.EmailAddressColumn] = value; + } + } + + /// Returns true if the TypedList field EmailAddress is NULL, false otherwise. + public bool IsEmailAddressNull() + { + return IsNull(_parent.EmailAddressColumn); + } + + /// Sets the TypedList field EmailAddress to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetEmailAddressNull() + { + this[_parent.EmailAddressColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field EmailAddressIsPublic

+ ///
+ /// Mapped on: User.EmailAddressIsPublic + public System.Boolean EmailAddressIsPublic + { + get + { + if(IsEmailAddressIsPublicNull()) + { + // return default value for this type. + return (System.Boolean)TypeDefaultValue.GetDefaultValue(typeof(System.Boolean)); + } + else + { + return (System.Boolean)this[_parent.EmailAddressIsPublicColumn]; + } + } + set + { + this[_parent.EmailAddressIsPublicColumn] = value; + } + } + + /// Returns true if the TypedList field EmailAddressIsPublic is NULL, false otherwise. + public bool IsEmailAddressIsPublicNull() + { + return IsNull(_parent.EmailAddressIsPublicColumn); + } + + /// Sets the TypedList field EmailAddressIsPublic to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetEmailAddressIsPublicNull() + { + this[_parent.EmailAddressIsPublicColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field NickName

+ ///
+ /// Mapped on: User.NickName + public System.String NickName + { + get + { + if(IsNickNameNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.NickNameColumn]; + } + } + set + { + this[_parent.NickNameColumn] = value; + } + } + + /// Returns true if the TypedList field NickName is NULL, false otherwise. + public bool IsNickNameNull() + { + return IsNull(_parent.NickNameColumn); + } + + /// Sets the TypedList field NickName to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetNickNameNull() + { + this[_parent.NickNameColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field MessageText

+ ///
+ /// Mapped on: Message.MessageText + public System.String MessageText + { + get + { + if(IsMessageTextNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.MessageTextColumn]; + } + } + set + { + this[_parent.MessageTextColumn] = value; + } + } + + /// Returns true if the TypedList field MessageText is NULL, false otherwise. + public bool IsMessageTextNull() + { + return IsNull(_parent.MessageTextColumn); + } + + /// Sets the TypedList field MessageText to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetMessageTextNull() + { + this[_parent.MessageTextColumn] = System.Convert.DBNull; + } + + + #endregion + + #region Custom Typed List Row Code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomTypedListRowCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + } +} diff --git a/DAL/TypedListClasses/ForumsWithSectionNameTypedList.cs b/DAL/TypedListClasses/ForumsWithSectionNameTypedList.cs new file mode 100644 index 0000000..b834dc6 --- /dev/null +++ b/DAL/TypedListClasses/ForumsWithSectionNameTypedList.cs @@ -0,0 +1,811 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Data; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.TypedListClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Typed datatable for the list 'ForumsWithSectionName'.

+ ///
+ /// + /// It embeds a fill method which accepts a filter. + /// The code doesn't support any changing of data. Users who do that are on their own. + /// It also doesn't support any event throwing. This list should be used as a base for readonly databinding + /// or dataview construction. + /// +#if !CF + [Serializable, System.ComponentModel.DesignerCategory("Code")] + [ToolboxItem(true)] + [DesignTimeVisible(true)] +#endif + public partial class ForumsWithSectionNameTypedList : TypedListBase, ITypedListLgp + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfacesList + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private DataColumn _columnForumID; + private DataColumn _columnForumName; + private DataColumn _columnSectionName; + private DataColumn _columnForumDescription; + private DataColumn _columnSectionID; + private DataColumn _columnForumOrderNo; + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalMembers + // __LLBLGENPRO_USER_CODE_REGION_END + private static Hashtable _customProperties; + private static Hashtable _fieldsCustomProperties; + #endregion + + #region Class Constants + /// The amount of fields in the resultset. + private const int AmountOfFields = 6; + #endregion + + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this + /// class or derived classes is constructed. + static ForumsWithSectionNameTypedList() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public ForumsWithSectionNameTypedList():base("ForumsWithSectionName") + { + InitClass(false); + } + + + /// CTor + /// The flag to signal the collection what kind of join statements to generate in the + /// query statement. Weak relationships are relationships which are optional, for example a + /// customer with no orders is possible, because the relationship between customer and order is based on a field in order. + /// When this property is set to true (default: false), weak relationships will result in LEFT JOIN statements. When + /// set to false (which is the default), INNER JOIN statements are used. + /// + public ForumsWithSectionNameTypedList(bool obeyWeakRelations):base("ForumsWithSectionName") + { + InitClass(obeyWeakRelations); + } + +#if !CF + /// Protected constructor for deserialization. + /// + /// + protected ForumsWithSectionNameTypedList(SerializationInfo info, StreamingContext context):base(info, context) + { + InitMembers(); + } +#endif + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will use no sort filter, no select filter, will allow duplicate rows and will not limit the amount of rows returned + /// true if fill succeeded, false otherwise + public bool Fill() + { + return Fill(0, null, true, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will not use a filter, will allow duplicate rows. + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, true, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will not use a filter. + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// true if fill succeeded, false otherwise + public virtual bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, transactionToUse, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// GroupByCollection with fields to group by on. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, + IGroupByCollection groupByClause) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, transactionToUse, groupByClause, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// GroupByCollection with fields to group by on. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if fill succeeded, false otherwise + public virtual bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, + IGroupByCollection groupByClause, int pageNumber, int pageSize) + { + IEntityFields fieldsInResultset = BuildResultset(); + IRelationCollection relations = BuildRelationSet(); + + TypedListDAO dao = DAOFactory.CreateTypedListDAO(); + return dao.GetMultiAsDataTable(fieldsInResultset, this, maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, allowDuplicates, groupByClause, transactionToUse, pageNumber, pageSize); + } + + + /// Gets the amount of rows in the database for this typed list, not skipping duplicates + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount() + { + return GetDbCount(true, null, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates) + { + return GetDbCount(allowDuplicates, null, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates, IPredicateExpression filter) + { + return GetDbCount(allowDuplicates, filter, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// The relations for the filter to apply + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates, IPredicateExpression filter, IRelationCollection relations) + { + return GetDbCount(allowDuplicates, filter, relations, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// The relations for the filter to apply + /// group by clause to embed in the query + /// the number of rows in the set defined by the passed in query elements + public virtual int GetDbCount(bool allowDuplicates, IPredicateExpression filter, IRelationCollection relations, GroupByCollection groupByClause) + { + IEntityFields fieldsInResultset = BuildResultset(); + IRelationCollection relationsToUse = BuildRelationSet(); + if(relations!=null) + { + for (int i = 0; i < relations.Count; i++) + { + relationsToUse.Add(relations[i]); + } + } + + TypedListDAO dao = DAOFactory.CreateTypedListDAO(); + return dao.GetDbCount(fieldsInResultset, null, filter, relationsToUse, groupByClause, allowDuplicates); + } + + + /// Builds the relation set for this typed list. + /// ready to use relation set + public virtual IRelationCollection BuildRelationSet() + { + IRelationCollection toReturn = new RelationCollection(); + toReturn.ObeyWeakRelations = base.ObeyWeakRelations; + toReturn.Add(ForumEntity.Relations.SectionEntityUsingSectionID, "", "", JoinHint.None); + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalRelations + // __LLBLGENPRO_USER_CODE_REGION_END + OnRelationSetBuilt(toReturn); + return toReturn; + } + + + /// Builds the resultset fields. + /// ready to use resultset + public virtual IEntityFields BuildResultset() + { + ResultsetFields toReturn = new ResultsetFields(AmountOfFields); + toReturn.DefineField(ForumFields.ForumID, 0, "ForumID", "", AggregateFunction.None); + toReturn.DefineField(ForumFields.ForumName, 1, "ForumName", "", AggregateFunction.None); + toReturn.DefineField(SectionFields.SectionName, 2, "SectionName", "", AggregateFunction.None); + toReturn.DefineField(ForumFields.ForumDescription, 3, "ForumDescription", "", AggregateFunction.None); + toReturn.DefineField(SectionFields.SectionID, 4, "SectionID", "", AggregateFunction.None); + toReturn.DefineField(ForumFields.OrderNo, 5, "ForumOrderNo", "", AggregateFunction.None); + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalFields + // be sure to call toReturn.Expand(number of new fields) first. + // __LLBLGENPRO_USER_CODE_REGION_END + OnResultsetBuilt(toReturn); + return toReturn; + } + + + /// Gets an array of all ForumsWithSectionNameRow objects. + /// Array with ForumsWithSectionNameRow objects + public new ForumsWithSectionNameRow[] Select() + { + return (ForumsWithSectionNameRow[])base.Select(); + } + + + /// Gets an array of all ForumsWithSectionNameRow objects that match the filter criteria in order of primary key (or lacking one, order of addition.) + /// The criteria to use to filter the rows. + /// Array with ForumsWithSectionNameRow objects + public new ForumsWithSectionNameRow[] Select(string filterExpression) + { + return (ForumsWithSectionNameRow[])base.Select(filterExpression); + } + + + /// Gets an array of all ForumsWithSectionNameRow objects that match the filter criteria, in the specified sort order + /// The filter expression. + /// A string specifying the column and sort direction. + /// Array with ForumsWithSectionNameRow objects + public new ForumsWithSectionNameRow[] Select(string filterExpression, string sort) + { + return (ForumsWithSectionNameRow[])base.Select(filterExpression, sort); + } + + + /// Gets an array of all ForumsWithSectionNameRow objects that match the filter criteria, in the specified sort order that match the specified state + /// The filter expression. + /// A string specifying the column and sort direction. + /// One of the values. + /// Array with ForumsWithSectionNameRow objects + public new ForumsWithSectionNameRow[] Select(string filterExpression, string sort, DataViewRowState recordStates) + { + return (ForumsWithSectionNameRow[])base.Select(filterExpression, sort, recordStates); + } + + + /// Creates a new typed row during the build of the datatable during a Fill session by a dataadapter. + /// supplied row builder to pass to the typed row + /// the new typed datarow + protected override DataRow NewRowFromBuilder(DataRowBuilder rowBuilder) + { + return new ForumsWithSectionNameRow(rowBuilder); + } + + + /// Initializes the hashtables for the typed list type and typed list field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Hashtable(); + _fieldsCustomProperties = new Hashtable(); + + Hashtable fieldHashtable = null; + + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ForumID", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ForumName", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("SectionName", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ForumDescription", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("SectionID", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ForumOrderNo", fieldHashtable); + } + + + /// Initialize the datastructures. + /// flag for the internal used relations object + protected override void InitClass(bool obeyWeakRelations) + { + + _columnForumID = new DataColumn("ForumID", typeof(System.Int32), null, MappingType.Element); + _columnForumID.ReadOnly = true; + _columnForumID.Caption = @"ForumID"; + this.Columns.Add(_columnForumID); + + _columnForumName = new DataColumn("ForumName", typeof(System.String), null, MappingType.Element); + _columnForumName.ReadOnly = true; + _columnForumName.Caption = @"ForumName"; + this.Columns.Add(_columnForumName); + + _columnSectionName = new DataColumn("SectionName", typeof(System.String), null, MappingType.Element); + _columnSectionName.ReadOnly = true; + _columnSectionName.Caption = @"SectionName"; + this.Columns.Add(_columnSectionName); + + _columnForumDescription = new DataColumn("ForumDescription", typeof(System.String), null, MappingType.Element); + _columnForumDescription.ReadOnly = true; + _columnForumDescription.Caption = @"ForumDescription"; + this.Columns.Add(_columnForumDescription); + + _columnSectionID = new DataColumn("SectionID", typeof(System.Int32), null, MappingType.Element); + _columnSectionID.ReadOnly = true; + _columnSectionID.Caption = @"SectionID"; + this.Columns.Add(_columnSectionID); + + _columnForumOrderNo = new DataColumn("ForumOrderNo", typeof(System.Int16), null, MappingType.Element); + _columnForumOrderNo.ReadOnly = true; + _columnForumOrderNo.Caption = @"OrderNo"; + this.Columns.Add(_columnForumOrderNo); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClass + // __LLBLGENPRO_USER_CODE_REGION_END + base.ObeyWeakRelations = obeyWeakRelations; + OnInitialized(); + } + + + /// Initializes the members, after a clone action. + private void InitMembers() + { + _columnForumID = this.Columns["ForumID"]; + _columnForumName = this.Columns["ForumName"]; + _columnSectionName = this.Columns["SectionName"]; + _columnForumDescription = this.Columns["ForumDescription"]; + _columnSectionID = this.Columns["SectionID"]; + _columnForumOrderNo = this.Columns["ForumOrderNo"]; + + // __LLBLGENPRO_USER_CODE_REGION_START InitMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitialized(); + } + + + /// Return the type of the typed datarow + /// returns the requested type + protected override Type GetRowType() + { + return typeof(ForumsWithSectionNameRow); + } + + + /// Clones this instance. + /// A clone of this instance + public override DataTable Clone() + { + ForumsWithSectionNameTypedList cloneToReturn = ((ForumsWithSectionNameTypedList)(base.Clone())); + cloneToReturn.InitMembers(); + return cloneToReturn; + } + +#if !CF + /// Creates a new instance of the DataTable class. + /// a new instance of a datatable with this schema. + protected override DataTable CreateInstance() + { + return new ForumsWithSectionNameTypedList(); + } +#endif + + #region Class Property Declarations + /// Returns the amount of rows in this typed list. + [System.ComponentModel.Browsable(false)] + public override int Count + { + get + { + return this.Rows.Count; + } + } + + /// The custom properties for this TypedList type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Hashtable CustomProperties + { + get { return _customProperties;} + } + + /// The custom properties for the type of this TypedList instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [System.ComponentModel.Browsable(false)] + public virtual Hashtable CustomPropertiesOfType + { + get { return ForumsWithSectionNameTypedList.CustomProperties;} + } + + /// The custom properties for the fields of this TypedList type. The returned Hashtable contains per fieldname a hashtable of name-value + /// pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Hashtable FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this TypedList instance. The returned Hashtable contains per fieldname a hashtable of name-value + /// pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [System.ComponentModel.Browsable(false)] + public virtual Hashtable FieldsCustomPropertiesOfType + { + get { return ForumsWithSectionNameTypedList.FieldsCustomProperties;} + } + + /// Indexer of this strong typed list + public ForumsWithSectionNameRow this[int index] + { + get + { + return ((ForumsWithSectionNameRow)(this.Rows[index])); + } + } + + + /// Returns the column object belonging to the TypedList field ForumID + internal DataColumn ForumIDColumn + { + get { return _columnForumID; } + } + + /// Returns the column object belonging to the TypedList field ForumName + internal DataColumn ForumNameColumn + { + get { return _columnForumName; } + } + + /// Returns the column object belonging to the TypedList field SectionName + internal DataColumn SectionNameColumn + { + get { return _columnSectionName; } + } + + /// Returns the column object belonging to the TypedList field ForumDescription + internal DataColumn ForumDescriptionColumn + { + get { return _columnForumDescription; } + } + + /// Returns the column object belonging to the TypedList field SectionID + internal DataColumn SectionIDColumn + { + get { return _columnSectionID; } + } + + /// Returns the column object belonging to the TypedList field ForumOrderNo + internal DataColumn ForumOrderNoColumn + { + get { return _columnForumOrderNo; } + } + + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalColumnProperties + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Custom TypedList code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomTypedListCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } + + + /// Typed datarow for the typed datatable ForumsWithSectionName + public partial class ForumsWithSectionNameRow : DataRow + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfacesRow + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private ForumsWithSectionNameTypedList _parent; + #endregion + + /// CTor + /// Row builder object to use when building this row + protected internal ForumsWithSectionNameRow(DataRowBuilder rowBuilder) : base(rowBuilder) + { + _parent = ((ForumsWithSectionNameTypedList)(this.Table)); + } + + + #region Class Property Declarations + + /// Gets / sets the value of the TypedList field ForumID

+ ///
+ /// Mapped on: Forum.ForumID + public System.Int32 ForumID + { + get + { + if(IsForumIDNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.ForumIDColumn]; + } + } + set + { + this[_parent.ForumIDColumn] = value; + } + } + + /// Returns true if the TypedList field ForumID is NULL, false otherwise. + public bool IsForumIDNull() + { + return IsNull(_parent.ForumIDColumn); + } + + /// Sets the TypedList field ForumID to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetForumIDNull() + { + this[_parent.ForumIDColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field ForumName

+ ///
+ /// Mapped on: Forum.ForumName + public System.String ForumName + { + get + { + if(IsForumNameNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.ForumNameColumn]; + } + } + set + { + this[_parent.ForumNameColumn] = value; + } + } + + /// Returns true if the TypedList field ForumName is NULL, false otherwise. + public bool IsForumNameNull() + { + return IsNull(_parent.ForumNameColumn); + } + + /// Sets the TypedList field ForumName to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetForumNameNull() + { + this[_parent.ForumNameColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field SectionName

+ ///
+ /// Mapped on: Section.SectionName + public System.String SectionName + { + get + { + if(IsSectionNameNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.SectionNameColumn]; + } + } + set + { + this[_parent.SectionNameColumn] = value; + } + } + + /// Returns true if the TypedList field SectionName is NULL, false otherwise. + public bool IsSectionNameNull() + { + return IsNull(_parent.SectionNameColumn); + } + + /// Sets the TypedList field SectionName to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetSectionNameNull() + { + this[_parent.SectionNameColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field ForumDescription

+ ///
+ /// Mapped on: Forum.ForumDescription + public System.String ForumDescription + { + get + { + if(IsForumDescriptionNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.ForumDescriptionColumn]; + } + } + set + { + this[_parent.ForumDescriptionColumn] = value; + } + } + + /// Returns true if the TypedList field ForumDescription is NULL, false otherwise. + public bool IsForumDescriptionNull() + { + return IsNull(_parent.ForumDescriptionColumn); + } + + /// Sets the TypedList field ForumDescription to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetForumDescriptionNull() + { + this[_parent.ForumDescriptionColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field SectionID

+ ///
+ /// Mapped on: Section.SectionID + public System.Int32 SectionID + { + get + { + if(IsSectionIDNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.SectionIDColumn]; + } + } + set + { + this[_parent.SectionIDColumn] = value; + } + } + + /// Returns true if the TypedList field SectionID is NULL, false otherwise. + public bool IsSectionIDNull() + { + return IsNull(_parent.SectionIDColumn); + } + + /// Sets the TypedList field SectionID to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetSectionIDNull() + { + this[_parent.SectionIDColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field ForumOrderNo

+ ///
+ /// Mapped on: Forum.OrderNo + public System.Int16 ForumOrderNo + { + get + { + if(IsForumOrderNoNull()) + { + // return default value for this type. + return (System.Int16)TypeDefaultValue.GetDefaultValue(typeof(System.Int16)); + } + else + { + return (System.Int16)this[_parent.ForumOrderNoColumn]; + } + } + set + { + this[_parent.ForumOrderNoColumn] = value; + } + } + + /// Returns true if the TypedList field ForumOrderNo is NULL, false otherwise. + public bool IsForumOrderNoNull() + { + return IsNull(_parent.ForumOrderNoColumn); + } + + /// Sets the TypedList field ForumOrderNo to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetForumOrderNoNull() + { + this[_parent.ForumOrderNoColumn] = System.Convert.DBNull; + } + + + #endregion + + #region Custom Typed List Row Code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomTypedListRowCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + } +} diff --git a/DAL/TypedListClasses/MessagesInThreadTypedList.cs b/DAL/TypedListClasses/MessagesInThreadTypedList.cs new file mode 100644 index 0000000..07a39e7 --- /dev/null +++ b/DAL/TypedListClasses/MessagesInThreadTypedList.cs @@ -0,0 +1,1190 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Data; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.TypedListClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Typed datatable for the list 'MessagesInThread'.

+ ///
+ /// + /// It embeds a fill method which accepts a filter. + /// The code doesn't support any changing of data. Users who do that are on their own. + /// It also doesn't support any event throwing. This list should be used as a base for readonly databinding + /// or dataview construction. + /// +#if !CF + [Serializable, System.ComponentModel.DesignerCategory("Code")] + [ToolboxItem(true)] + [DesignTimeVisible(true)] +#endif + public partial class MessagesInThreadTypedList : TypedListBase, ITypedListLgp + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfacesList + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private DataColumn _columnMessageID; + private DataColumn _columnPostingDate; + private DataColumn _columnMessageTextAsHTML; + private DataColumn _columnThreadID; + private DataColumn _columnPostedFromIP; + private DataColumn _columnUserID; + private DataColumn _columnNickName; + private DataColumn _columnSignatureAsHTML; + private DataColumn _columnIconURL; + private DataColumn _columnLocation; + private DataColumn _columnJoinDate; + private DataColumn _columnAmountOfPostings; + private DataColumn _columnUserTitleDescription; + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalMembers + // __LLBLGENPRO_USER_CODE_REGION_END + private static Hashtable _customProperties; + private static Hashtable _fieldsCustomProperties; + #endregion + + #region Class Constants + /// The amount of fields in the resultset. + private const int AmountOfFields = 13; + #endregion + + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this + /// class or derived classes is constructed. + static MessagesInThreadTypedList() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public MessagesInThreadTypedList():base("MessagesInThread") + { + InitClass(false); + } + + + /// CTor + /// The flag to signal the collection what kind of join statements to generate in the + /// query statement. Weak relationships are relationships which are optional, for example a + /// customer with no orders is possible, because the relationship between customer and order is based on a field in order. + /// When this property is set to true (default: false), weak relationships will result in LEFT JOIN statements. When + /// set to false (which is the default), INNER JOIN statements are used. + /// + public MessagesInThreadTypedList(bool obeyWeakRelations):base("MessagesInThread") + { + InitClass(obeyWeakRelations); + } + +#if !CF + /// Protected constructor for deserialization. + /// + /// + protected MessagesInThreadTypedList(SerializationInfo info, StreamingContext context):base(info, context) + { + InitMembers(); + } +#endif + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will use no sort filter, no select filter, will allow duplicate rows and will not limit the amount of rows returned + /// true if fill succeeded, false otherwise + public bool Fill() + { + return Fill(0, null, true, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will not use a filter, will allow duplicate rows. + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, true, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will not use a filter. + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// true if fill succeeded, false otherwise + public virtual bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, transactionToUse, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// GroupByCollection with fields to group by on. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, + IGroupByCollection groupByClause) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, transactionToUse, groupByClause, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// GroupByCollection with fields to group by on. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if fill succeeded, false otherwise + public virtual bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, + IGroupByCollection groupByClause, int pageNumber, int pageSize) + { + IEntityFields fieldsInResultset = BuildResultset(); + IRelationCollection relations = BuildRelationSet(); + + TypedListDAO dao = DAOFactory.CreateTypedListDAO(); + return dao.GetMultiAsDataTable(fieldsInResultset, this, maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, allowDuplicates, groupByClause, transactionToUse, pageNumber, pageSize); + } + + + /// Gets the amount of rows in the database for this typed list, not skipping duplicates + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount() + { + return GetDbCount(true, null, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates) + { + return GetDbCount(allowDuplicates, null, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates, IPredicateExpression filter) + { + return GetDbCount(allowDuplicates, filter, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// The relations for the filter to apply + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates, IPredicateExpression filter, IRelationCollection relations) + { + return GetDbCount(allowDuplicates, filter, relations, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// The relations for the filter to apply + /// group by clause to embed in the query + /// the number of rows in the set defined by the passed in query elements + public virtual int GetDbCount(bool allowDuplicates, IPredicateExpression filter, IRelationCollection relations, GroupByCollection groupByClause) + { + IEntityFields fieldsInResultset = BuildResultset(); + IRelationCollection relationsToUse = BuildRelationSet(); + if(relations!=null) + { + for (int i = 0; i < relations.Count; i++) + { + relationsToUse.Add(relations[i]); + } + } + + TypedListDAO dao = DAOFactory.CreateTypedListDAO(); + return dao.GetDbCount(fieldsInResultset, null, filter, relationsToUse, groupByClause, allowDuplicates); + } + + + /// Builds the relation set for this typed list. + /// ready to use relation set + public virtual IRelationCollection BuildRelationSet() + { + IRelationCollection toReturn = new RelationCollection(); + toReturn.ObeyWeakRelations = base.ObeyWeakRelations; + toReturn.Add(MessageEntity.Relations.UserEntityUsingPostedByUserID, "", "", JoinHint.Left); + toReturn.Add(UserEntity.Relations.UserTitleEntityUsingUserTitleID, "", "", JoinHint.None); + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalRelations + // __LLBLGENPRO_USER_CODE_REGION_END + OnRelationSetBuilt(toReturn); + return toReturn; + } + + + /// Builds the resultset fields. + /// ready to use resultset + public virtual IEntityFields BuildResultset() + { + ResultsetFields toReturn = new ResultsetFields(AmountOfFields); + toReturn.DefineField(MessageFields.MessageID, 0, "MessageID", "", AggregateFunction.None); + toReturn.DefineField(MessageFields.PostingDate, 1, "PostingDate", "", AggregateFunction.None); + toReturn.DefineField(MessageFields.MessageTextAsHTML, 2, "MessageTextAsHTML", "", AggregateFunction.None); + toReturn.DefineField(MessageFields.ThreadID, 3, "ThreadID", "", AggregateFunction.None); + toReturn.DefineField(MessageFields.PostedFromIP, 4, "PostedFromIP", "", AggregateFunction.None); + toReturn.DefineField(UserFields.UserID, 5, "UserID", "", AggregateFunction.None); + toReturn.DefineField(UserFields.NickName, 6, "NickName", "", AggregateFunction.None); + toReturn.DefineField(UserFields.SignatureAsHTML, 7, "SignatureAsHTML", "", AggregateFunction.None); + toReturn.DefineField(UserFields.IconURL, 8, "IconURL", "", AggregateFunction.None); + toReturn.DefineField(UserFields.Location, 9, "Location", "", AggregateFunction.None); + toReturn.DefineField(UserFields.JoinDate, 10, "JoinDate", "", AggregateFunction.None); + toReturn.DefineField(UserFields.AmountOfPostings, 11, "AmountOfPostings", "", AggregateFunction.None); + toReturn.DefineField(UserTitleFields.UserTitleDescription, 12, "UserTitleDescription", "", AggregateFunction.None); + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalFields + // be sure to call toReturn.Expand(number of new fields) first. + // __LLBLGENPRO_USER_CODE_REGION_END + OnResultsetBuilt(toReturn); + return toReturn; + } + + + /// Gets an array of all MessagesInThreadRow objects. + /// Array with MessagesInThreadRow objects + public new MessagesInThreadRow[] Select() + { + return (MessagesInThreadRow[])base.Select(); + } + + + /// Gets an array of all MessagesInThreadRow objects that match the filter criteria in order of primary key (or lacking one, order of addition.) + /// The criteria to use to filter the rows. + /// Array with MessagesInThreadRow objects + public new MessagesInThreadRow[] Select(string filterExpression) + { + return (MessagesInThreadRow[])base.Select(filterExpression); + } + + + /// Gets an array of all MessagesInThreadRow objects that match the filter criteria, in the specified sort order + /// The filter expression. + /// A string specifying the column and sort direction. + /// Array with MessagesInThreadRow objects + public new MessagesInThreadRow[] Select(string filterExpression, string sort) + { + return (MessagesInThreadRow[])base.Select(filterExpression, sort); + } + + + /// Gets an array of all MessagesInThreadRow objects that match the filter criteria, in the specified sort order that match the specified state + /// The filter expression. + /// A string specifying the column and sort direction. + /// One of the values. + /// Array with MessagesInThreadRow objects + public new MessagesInThreadRow[] Select(string filterExpression, string sort, DataViewRowState recordStates) + { + return (MessagesInThreadRow[])base.Select(filterExpression, sort, recordStates); + } + + + /// Creates a new typed row during the build of the datatable during a Fill session by a dataadapter. + /// supplied row builder to pass to the typed row + /// the new typed datarow + protected override DataRow NewRowFromBuilder(DataRowBuilder rowBuilder) + { + return new MessagesInThreadRow(rowBuilder); + } + + + /// Initializes the hashtables for the typed list type and typed list field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Hashtable(); + _fieldsCustomProperties = new Hashtable(); + + Hashtable fieldHashtable = null; + + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("MessageID", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("PostingDate", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("MessageTextAsHTML", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("PostedFromIP", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("UserID", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("NickName", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("SignatureAsHTML", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("IconURL", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("Location", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("JoinDate", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("AmountOfPostings", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("UserTitleDescription", fieldHashtable); + } + + + /// Initialize the datastructures. + /// flag for the internal used relations object + protected override void InitClass(bool obeyWeakRelations) + { + + _columnMessageID = new DataColumn("MessageID", typeof(System.Int32), null, MappingType.Element); + _columnMessageID.ReadOnly = true; + _columnMessageID.Caption = @"MessageID"; + this.Columns.Add(_columnMessageID); + + _columnPostingDate = new DataColumn("PostingDate", typeof(System.DateTime), null, MappingType.Element); + _columnPostingDate.ReadOnly = true; + _columnPostingDate.Caption = @"PostingDate"; + this.Columns.Add(_columnPostingDate); + + _columnMessageTextAsHTML = new DataColumn("MessageTextAsHTML", typeof(System.String), null, MappingType.Element); + _columnMessageTextAsHTML.ReadOnly = true; + _columnMessageTextAsHTML.Caption = @"MessageTextAsHTML"; + this.Columns.Add(_columnMessageTextAsHTML); + + _columnThreadID = new DataColumn("ThreadID", typeof(System.Int32), null, MappingType.Element); + _columnThreadID.ReadOnly = true; + _columnThreadID.Caption = @"ThreadID"; + this.Columns.Add(_columnThreadID); + + _columnPostedFromIP = new DataColumn("PostedFromIP", typeof(System.String), null, MappingType.Element); + _columnPostedFromIP.ReadOnly = true; + _columnPostedFromIP.Caption = @"PostedFromIP"; + this.Columns.Add(_columnPostedFromIP); + + _columnUserID = new DataColumn("UserID", typeof(System.Int32), null, MappingType.Element); + _columnUserID.ReadOnly = true; + _columnUserID.Caption = @"UserID"; + this.Columns.Add(_columnUserID); + + _columnNickName = new DataColumn("NickName", typeof(System.String), null, MappingType.Element); + _columnNickName.ReadOnly = true; + _columnNickName.Caption = @"NickName"; + this.Columns.Add(_columnNickName); + + _columnSignatureAsHTML = new DataColumn("SignatureAsHTML", typeof(System.String), null, MappingType.Element); + _columnSignatureAsHTML.ReadOnly = true; + _columnSignatureAsHTML.Caption = @"SignatureAsHTML"; + this.Columns.Add(_columnSignatureAsHTML); + + _columnIconURL = new DataColumn("IconURL", typeof(System.String), null, MappingType.Element); + _columnIconURL.ReadOnly = true; + _columnIconURL.Caption = @"IconURL"; + this.Columns.Add(_columnIconURL); + + _columnLocation = new DataColumn("Location", typeof(System.String), null, MappingType.Element); + _columnLocation.ReadOnly = true; + _columnLocation.Caption = @"Location"; + this.Columns.Add(_columnLocation); + + _columnJoinDate = new DataColumn("JoinDate", typeof(System.DateTime), null, MappingType.Element); + _columnJoinDate.ReadOnly = true; + _columnJoinDate.Caption = @"JoinDate"; + this.Columns.Add(_columnJoinDate); + + _columnAmountOfPostings = new DataColumn("AmountOfPostings", typeof(System.Int32), null, MappingType.Element); + _columnAmountOfPostings.ReadOnly = true; + _columnAmountOfPostings.Caption = @"AmountOfPostings"; + this.Columns.Add(_columnAmountOfPostings); + + _columnUserTitleDescription = new DataColumn("UserTitleDescription", typeof(System.String), null, MappingType.Element); + _columnUserTitleDescription.ReadOnly = true; + _columnUserTitleDescription.Caption = @"UserTitleDescription"; + this.Columns.Add(_columnUserTitleDescription); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClass + // __LLBLGENPRO_USER_CODE_REGION_END + base.ObeyWeakRelations = obeyWeakRelations; + OnInitialized(); + } + + + /// Initializes the members, after a clone action. + private void InitMembers() + { + _columnMessageID = this.Columns["MessageID"]; + _columnPostingDate = this.Columns["PostingDate"]; + _columnMessageTextAsHTML = this.Columns["MessageTextAsHTML"]; + _columnThreadID = this.Columns["ThreadID"]; + _columnPostedFromIP = this.Columns["PostedFromIP"]; + _columnUserID = this.Columns["UserID"]; + _columnNickName = this.Columns["NickName"]; + _columnSignatureAsHTML = this.Columns["SignatureAsHTML"]; + _columnIconURL = this.Columns["IconURL"]; + _columnLocation = this.Columns["Location"]; + _columnJoinDate = this.Columns["JoinDate"]; + _columnAmountOfPostings = this.Columns["AmountOfPostings"]; + _columnUserTitleDescription = this.Columns["UserTitleDescription"]; + + // __LLBLGENPRO_USER_CODE_REGION_START InitMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitialized(); + } + + + /// Return the type of the typed datarow + /// returns the requested type + protected override Type GetRowType() + { + return typeof(MessagesInThreadRow); + } + + + /// Clones this instance. + /// A clone of this instance + public override DataTable Clone() + { + MessagesInThreadTypedList cloneToReturn = ((MessagesInThreadTypedList)(base.Clone())); + cloneToReturn.InitMembers(); + return cloneToReturn; + } + +#if !CF + /// Creates a new instance of the DataTable class. + /// a new instance of a datatable with this schema. + protected override DataTable CreateInstance() + { + return new MessagesInThreadTypedList(); + } +#endif + + #region Class Property Declarations + /// Returns the amount of rows in this typed list. + [System.ComponentModel.Browsable(false)] + public override int Count + { + get + { + return this.Rows.Count; + } + } + + /// The custom properties for this TypedList type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Hashtable CustomProperties + { + get { return _customProperties;} + } + + /// The custom properties for the type of this TypedList instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [System.ComponentModel.Browsable(false)] + public virtual Hashtable CustomPropertiesOfType + { + get { return MessagesInThreadTypedList.CustomProperties;} + } + + /// The custom properties for the fields of this TypedList type. The returned Hashtable contains per fieldname a hashtable of name-value + /// pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Hashtable FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this TypedList instance. The returned Hashtable contains per fieldname a hashtable of name-value + /// pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [System.ComponentModel.Browsable(false)] + public virtual Hashtable FieldsCustomPropertiesOfType + { + get { return MessagesInThreadTypedList.FieldsCustomProperties;} + } + + /// Indexer of this strong typed list + public MessagesInThreadRow this[int index] + { + get + { + return ((MessagesInThreadRow)(this.Rows[index])); + } + } + + + /// Returns the column object belonging to the TypedList field MessageID + internal DataColumn MessageIDColumn + { + get { return _columnMessageID; } + } + + /// Returns the column object belonging to the TypedList field PostingDate + internal DataColumn PostingDateColumn + { + get { return _columnPostingDate; } + } + + /// Returns the column object belonging to the TypedList field MessageTextAsHTML + internal DataColumn MessageTextAsHTMLColumn + { + get { return _columnMessageTextAsHTML; } + } + + /// Returns the column object belonging to the TypedList field ThreadID + internal DataColumn ThreadIDColumn + { + get { return _columnThreadID; } + } + + /// Returns the column object belonging to the TypedList field PostedFromIP + internal DataColumn PostedFromIPColumn + { + get { return _columnPostedFromIP; } + } + + /// Returns the column object belonging to the TypedList field UserID + internal DataColumn UserIDColumn + { + get { return _columnUserID; } + } + + /// Returns the column object belonging to the TypedList field NickName + internal DataColumn NickNameColumn + { + get { return _columnNickName; } + } + + /// Returns the column object belonging to the TypedList field SignatureAsHTML + internal DataColumn SignatureAsHTMLColumn + { + get { return _columnSignatureAsHTML; } + } + + /// Returns the column object belonging to the TypedList field IconURL + internal DataColumn IconURLColumn + { + get { return _columnIconURL; } + } + + /// Returns the column object belonging to the TypedList field Location + internal DataColumn LocationColumn + { + get { return _columnLocation; } + } + + /// Returns the column object belonging to the TypedList field JoinDate + internal DataColumn JoinDateColumn + { + get { return _columnJoinDate; } + } + + /// Returns the column object belonging to the TypedList field AmountOfPostings + internal DataColumn AmountOfPostingsColumn + { + get { return _columnAmountOfPostings; } + } + + /// Returns the column object belonging to the TypedList field UserTitleDescription + internal DataColumn UserTitleDescriptionColumn + { + get { return _columnUserTitleDescription; } + } + + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalColumnProperties + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Custom TypedList code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomTypedListCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } + + + /// Typed datarow for the typed datatable MessagesInThread + public partial class MessagesInThreadRow : DataRow + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfacesRow + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private MessagesInThreadTypedList _parent; + #endregion + + /// CTor + /// Row builder object to use when building this row + protected internal MessagesInThreadRow(DataRowBuilder rowBuilder) : base(rowBuilder) + { + _parent = ((MessagesInThreadTypedList)(this.Table)); + } + + + #region Class Property Declarations + + /// Gets / sets the value of the TypedList field MessageID

+ ///
+ /// Mapped on: Message.MessageID + public System.Int32 MessageID + { + get + { + if(IsMessageIDNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.MessageIDColumn]; + } + } + set + { + this[_parent.MessageIDColumn] = value; + } + } + + /// Returns true if the TypedList field MessageID is NULL, false otherwise. + public bool IsMessageIDNull() + { + return IsNull(_parent.MessageIDColumn); + } + + /// Sets the TypedList field MessageID to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetMessageIDNull() + { + this[_parent.MessageIDColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field PostingDate

+ ///
+ /// Mapped on: Message.PostingDate + public System.DateTime PostingDate + { + get + { + if(IsPostingDateNull()) + { + // return default value for this type. + return (System.DateTime)TypeDefaultValue.GetDefaultValue(typeof(System.DateTime)); + } + else + { + return (System.DateTime)this[_parent.PostingDateColumn]; + } + } + set + { + this[_parent.PostingDateColumn] = value; + } + } + + /// Returns true if the TypedList field PostingDate is NULL, false otherwise. + public bool IsPostingDateNull() + { + return IsNull(_parent.PostingDateColumn); + } + + /// Sets the TypedList field PostingDate to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetPostingDateNull() + { + this[_parent.PostingDateColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field MessageTextAsHTML

+ ///
+ /// Mapped on: Message.MessageTextAsHTML + public System.String MessageTextAsHTML + { + get + { + if(IsMessageTextAsHTMLNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.MessageTextAsHTMLColumn]; + } + } + set + { + this[_parent.MessageTextAsHTMLColumn] = value; + } + } + + /// Returns true if the TypedList field MessageTextAsHTML is NULL, false otherwise. + public bool IsMessageTextAsHTMLNull() + { + return IsNull(_parent.MessageTextAsHTMLColumn); + } + + /// Sets the TypedList field MessageTextAsHTML to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetMessageTextAsHTMLNull() + { + this[_parent.MessageTextAsHTMLColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field ThreadID

+ ///
+ /// Mapped on: Message.ThreadID + public System.Int32 ThreadID + { + get + { + if(IsThreadIDNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.ThreadIDColumn]; + } + } + set + { + this[_parent.ThreadIDColumn] = value; + } + } + + /// Returns true if the TypedList field ThreadID is NULL, false otherwise. + public bool IsThreadIDNull() + { + return IsNull(_parent.ThreadIDColumn); + } + + /// Sets the TypedList field ThreadID to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetThreadIDNull() + { + this[_parent.ThreadIDColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field PostedFromIP

+ ///
+ /// Mapped on: Message.PostedFromIP + public System.String PostedFromIP + { + get + { + if(IsPostedFromIPNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.PostedFromIPColumn]; + } + } + set + { + this[_parent.PostedFromIPColumn] = value; + } + } + + /// Returns true if the TypedList field PostedFromIP is NULL, false otherwise. + public bool IsPostedFromIPNull() + { + return IsNull(_parent.PostedFromIPColumn); + } + + /// Sets the TypedList field PostedFromIP to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetPostedFromIPNull() + { + this[_parent.PostedFromIPColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field UserID

+ ///
+ /// Mapped on: User.UserID + public System.Int32 UserID + { + get + { + if(IsUserIDNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.UserIDColumn]; + } + } + set + { + this[_parent.UserIDColumn] = value; + } + } + + /// Returns true if the TypedList field UserID is NULL, false otherwise. + public bool IsUserIDNull() + { + return IsNull(_parent.UserIDColumn); + } + + /// Sets the TypedList field UserID to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetUserIDNull() + { + this[_parent.UserIDColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field NickName

+ ///
+ /// Mapped on: User.NickName + public System.String NickName + { + get + { + if(IsNickNameNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.NickNameColumn]; + } + } + set + { + this[_parent.NickNameColumn] = value; + } + } + + /// Returns true if the TypedList field NickName is NULL, false otherwise. + public bool IsNickNameNull() + { + return IsNull(_parent.NickNameColumn); + } + + /// Sets the TypedList field NickName to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetNickNameNull() + { + this[_parent.NickNameColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field SignatureAsHTML

+ ///
+ /// Mapped on: User.SignatureAsHTML + public System.String SignatureAsHTML + { + get + { + if(IsSignatureAsHTMLNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.SignatureAsHTMLColumn]; + } + } + set + { + this[_parent.SignatureAsHTMLColumn] = value; + } + } + + /// Returns true if the TypedList field SignatureAsHTML is NULL, false otherwise. + public bool IsSignatureAsHTMLNull() + { + return IsNull(_parent.SignatureAsHTMLColumn); + } + + /// Sets the TypedList field SignatureAsHTML to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetSignatureAsHTMLNull() + { + this[_parent.SignatureAsHTMLColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field IconURL

+ ///
+ /// Mapped on: User.IconURL + public System.String IconURL + { + get + { + if(IsIconURLNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.IconURLColumn]; + } + } + set + { + this[_parent.IconURLColumn] = value; + } + } + + /// Returns true if the TypedList field IconURL is NULL, false otherwise. + public bool IsIconURLNull() + { + return IsNull(_parent.IconURLColumn); + } + + /// Sets the TypedList field IconURL to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetIconURLNull() + { + this[_parent.IconURLColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field Location

+ ///
+ /// Mapped on: User.Location + public System.String Location + { + get + { + if(IsLocationNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.LocationColumn]; + } + } + set + { + this[_parent.LocationColumn] = value; + } + } + + /// Returns true if the TypedList field Location is NULL, false otherwise. + public bool IsLocationNull() + { + return IsNull(_parent.LocationColumn); + } + + /// Sets the TypedList field Location to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetLocationNull() + { + this[_parent.LocationColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field JoinDate

+ ///
+ /// Mapped on: User.JoinDate + public System.DateTime JoinDate + { + get + { + if(IsJoinDateNull()) + { + // return default value for this type. + return (System.DateTime)TypeDefaultValue.GetDefaultValue(typeof(System.DateTime)); + } + else + { + return (System.DateTime)this[_parent.JoinDateColumn]; + } + } + set + { + this[_parent.JoinDateColumn] = value; + } + } + + /// Returns true if the TypedList field JoinDate is NULL, false otherwise. + public bool IsJoinDateNull() + { + return IsNull(_parent.JoinDateColumn); + } + + /// Sets the TypedList field JoinDate to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetJoinDateNull() + { + this[_parent.JoinDateColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field AmountOfPostings

+ ///
+ /// Mapped on: User.AmountOfPostings + public System.Int32 AmountOfPostings + { + get + { + if(IsAmountOfPostingsNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.AmountOfPostingsColumn]; + } + } + set + { + this[_parent.AmountOfPostingsColumn] = value; + } + } + + /// Returns true if the TypedList field AmountOfPostings is NULL, false otherwise. + public bool IsAmountOfPostingsNull() + { + return IsNull(_parent.AmountOfPostingsColumn); + } + + /// Sets the TypedList field AmountOfPostings to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetAmountOfPostingsNull() + { + this[_parent.AmountOfPostingsColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field UserTitleDescription

+ ///
+ /// Mapped on: UserTitle.UserTitleDescription + public System.String UserTitleDescription + { + get + { + if(IsUserTitleDescriptionNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.UserTitleDescriptionColumn]; + } + } + set + { + this[_parent.UserTitleDescriptionColumn] = value; + } + } + + /// Returns true if the TypedList field UserTitleDescription is NULL, false otherwise. + public bool IsUserTitleDescriptionNull() + { + return IsNull(_parent.UserTitleDescriptionColumn); + } + + /// Sets the TypedList field UserTitleDescription to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetUserTitleDescriptionNull() + { + this[_parent.UserTitleDescriptionColumn] = System.Convert.DBNull; + } + + + #endregion + + #region Custom Typed List Row Code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomTypedListRowCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + } +} diff --git a/DAL/TypedListClasses/SearchResultTypedList.cs b/DAL/TypedListClasses/SearchResultTypedList.cs new file mode 100644 index 0000000..9ca45ee --- /dev/null +++ b/DAL/TypedListClasses/SearchResultTypedList.cs @@ -0,0 +1,759 @@ +/////////////////////////////////////////////////////////////// +// This is generated code. +////////////////////////////////////////////////////////////// +// Code is generated using LLBLGen Pro version: 2.6 +// Code is generated on: +// Code is generated using templates: SD.TemplateBindings.SharedTemplates.NET20 +// Templates vendor: Solutions Design. +// Templates version: +////////////////////////////////////////////////////////////// +using System; +using System.ComponentModel; +using System.Data; +using System.Collections; +#if !CF +using System.Runtime.Serialization; +#endif + +using SD.HnD.DAL.HelperClasses; +using SD.HnD.DAL.DaoClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.FactoryClasses; + +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.DAL.TypedListClasses +{ + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces + // __LLBLGENPRO_USER_CODE_REGION_END + + /// + /// Typed datatable for the list 'SearchResult'.

+ ///
+ /// + /// It embeds a fill method which accepts a filter. + /// The code doesn't support any changing of data. Users who do that are on their own. + /// It also doesn't support any event throwing. This list should be used as a base for readonly databinding + /// or dataview construction. + /// +#if !CF + [Serializable, System.ComponentModel.DesignerCategory("Code")] + [ToolboxItem(true)] + [DesignTimeVisible(true)] +#endif + public partial class SearchResultTypedList : TypedListBase, ITypedListLgp + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfacesList + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private DataColumn _columnThreadID; + private DataColumn _columnSubject; + private DataColumn _columnForumName; + private DataColumn _columnSectionName; + private DataColumn _columnThreadLastPostingDate; + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalMembers + // __LLBLGENPRO_USER_CODE_REGION_END + private static Hashtable _customProperties; + private static Hashtable _fieldsCustomProperties; + #endregion + + #region Class Constants + /// The amount of fields in the resultset. + private const int AmountOfFields = 5; + #endregion + + + /// Static CTor for setting up custom property hashtables. Is executed before the first instance of this + /// class or derived classes is constructed. + static SearchResultTypedList() + { + SetupCustomPropertyHashtables(); + } + + /// CTor + public SearchResultTypedList():base("SearchResult") + { + InitClass(false); + } + + + /// CTor + /// The flag to signal the collection what kind of join statements to generate in the + /// query statement. Weak relationships are relationships which are optional, for example a + /// customer with no orders is possible, because the relationship between customer and order is based on a field in order. + /// When this property is set to true (default: false), weak relationships will result in LEFT JOIN statements. When + /// set to false (which is the default), INNER JOIN statements are used. + /// + public SearchResultTypedList(bool obeyWeakRelations):base("SearchResult") + { + InitClass(obeyWeakRelations); + } + +#if !CF + /// Protected constructor for deserialization. + /// + /// + protected SearchResultTypedList(SerializationInfo info, StreamingContext context):base(info, context) + { + InitMembers(); + } +#endif + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will use no sort filter, no select filter, will allow duplicate rows and will not limit the amount of rows returned + /// true if fill succeeded, false otherwise + public bool Fill() + { + return Fill(0, null, true, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will not use a filter, will allow duplicate rows. + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, true, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query. + /// Will not use a filter. + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, null, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// true if fill succeeded, false otherwise + public virtual bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, null, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, transactionToUse, null, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// GroupByCollection with fields to group by on. + /// true if fill succeeded, false otherwise + public bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, + IGroupByCollection groupByClause) + { + return Fill(maxNumberOfItemsToReturn, sortClauses, allowDuplicates, selectFilter, transactionToUse, groupByClause, 0, 0); + } + + + /// Fills itself with data. it builds a dynamic query and loads itself with that query, using the specified filter + /// The maximum amount of rows to return. specifying 0 means all rows are returned + /// The order by specifications for the sorting of the resultset. When null is specified, no sorting is applied. + /// Flag to allow duplicate rows (true) or not (false) + /// Predicate which is used to filter the rows to insert in this Typed List instance + /// The transaction object to use. Can be null. If specified, the connection object of the transaction is + /// used to fill the TypedView, which avoids deadlocks on SqlServer. + /// GroupByCollection with fields to group by on. + /// The page number to retrieve. + /// The page size of the page to retrieve. + /// true if fill succeeded, false otherwise + public virtual bool Fill(long maxNumberOfItemsToReturn, ISortExpression sortClauses, bool allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, + IGroupByCollection groupByClause, int pageNumber, int pageSize) + { + IEntityFields fieldsInResultset = BuildResultset(); + IRelationCollection relations = BuildRelationSet(); + + TypedListDAO dao = DAOFactory.CreateTypedListDAO(); + return dao.GetMultiAsDataTable(fieldsInResultset, this, maxNumberOfItemsToReturn, sortClauses, selectFilter, relations, allowDuplicates, groupByClause, transactionToUse, pageNumber, pageSize); + } + + + /// Gets the amount of rows in the database for this typed list, not skipping duplicates + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount() + { + return GetDbCount(true, null, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates) + { + return GetDbCount(allowDuplicates, null, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates, IPredicateExpression filter) + { + return GetDbCount(allowDuplicates, filter, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// The relations for the filter to apply + /// the number of rows in the set defined by the passed in query elements + public int GetDbCount(bool allowDuplicates, IPredicateExpression filter, IRelationCollection relations) + { + return GetDbCount(allowDuplicates, filter, relations, null); + } + + + /// Gets the amount of rows in the database for this typed list. + /// Flag to allow duplicate rows (true) or not (false) + /// The filter to apply for the count retrieval + /// The relations for the filter to apply + /// group by clause to embed in the query + /// the number of rows in the set defined by the passed in query elements + public virtual int GetDbCount(bool allowDuplicates, IPredicateExpression filter, IRelationCollection relations, GroupByCollection groupByClause) + { + IEntityFields fieldsInResultset = BuildResultset(); + IRelationCollection relationsToUse = BuildRelationSet(); + if(relations!=null) + { + for (int i = 0; i < relations.Count; i++) + { + relationsToUse.Add(relations[i]); + } + } + + TypedListDAO dao = DAOFactory.CreateTypedListDAO(); + return dao.GetDbCount(fieldsInResultset, null, filter, relationsToUse, groupByClause, allowDuplicates); + } + + + /// Builds the relation set for this typed list. + /// ready to use relation set + public virtual IRelationCollection BuildRelationSet() + { + IRelationCollection toReturn = new RelationCollection(); + toReturn.ObeyWeakRelations = base.ObeyWeakRelations; + toReturn.Add(MessageEntity.Relations.ThreadEntityUsingThreadID, "", "", JoinHint.None); + toReturn.Add(ThreadEntity.Relations.ForumEntityUsingForumID, "", "", JoinHint.None); + toReturn.Add(ForumEntity.Relations.SectionEntityUsingSectionID, "", "", JoinHint.None); + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalRelations + // __LLBLGENPRO_USER_CODE_REGION_END + OnRelationSetBuilt(toReturn); + return toReturn; + } + + + /// Builds the resultset fields. + /// ready to use resultset + public virtual IEntityFields BuildResultset() + { + ResultsetFields toReturn = new ResultsetFields(AmountOfFields); + toReturn.DefineField(ThreadFields.ThreadID, 0, "ThreadID", "", AggregateFunction.None); + toReturn.DefineField(ThreadFields.Subject, 1, "Subject", "", AggregateFunction.None); + toReturn.DefineField(ForumFields.ForumName, 2, "ForumName", "", AggregateFunction.None); + toReturn.DefineField(SectionFields.SectionName, 3, "SectionName", "", AggregateFunction.None); + toReturn.DefineField(ThreadFields.ThreadLastPostingDate, 4, "ThreadLastPostingDate", "", AggregateFunction.None); + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalFields + // be sure to call toReturn.Expand(number of new fields) first. + // __LLBLGENPRO_USER_CODE_REGION_END + OnResultsetBuilt(toReturn); + return toReturn; + } + + + /// Gets an array of all SearchResultRow objects. + /// Array with SearchResultRow objects + public new SearchResultRow[] Select() + { + return (SearchResultRow[])base.Select(); + } + + + /// Gets an array of all SearchResultRow objects that match the filter criteria in order of primary key (or lacking one, order of addition.) + /// The criteria to use to filter the rows. + /// Array with SearchResultRow objects + public new SearchResultRow[] Select(string filterExpression) + { + return (SearchResultRow[])base.Select(filterExpression); + } + + + /// Gets an array of all SearchResultRow objects that match the filter criteria, in the specified sort order + /// The filter expression. + /// A string specifying the column and sort direction. + /// Array with SearchResultRow objects + public new SearchResultRow[] Select(string filterExpression, string sort) + { + return (SearchResultRow[])base.Select(filterExpression, sort); + } + + + /// Gets an array of all SearchResultRow objects that match the filter criteria, in the specified sort order that match the specified state + /// The filter expression. + /// A string specifying the column and sort direction. + /// One of the values. + /// Array with SearchResultRow objects + public new SearchResultRow[] Select(string filterExpression, string sort, DataViewRowState recordStates) + { + return (SearchResultRow[])base.Select(filterExpression, sort, recordStates); + } + + + /// Creates a new typed row during the build of the datatable during a Fill session by a dataadapter. + /// supplied row builder to pass to the typed row + /// the new typed datarow + protected override DataRow NewRowFromBuilder(DataRowBuilder rowBuilder) + { + return new SearchResultRow(rowBuilder); + } + + + /// Initializes the hashtables for the typed list type and typed list field custom properties. + private static void SetupCustomPropertyHashtables() + { + _customProperties = new Hashtable(); + _fieldsCustomProperties = new Hashtable(); + + Hashtable fieldHashtable = null; + + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ThreadID", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("Subject", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ForumName", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("SectionName", fieldHashtable); + fieldHashtable = new Hashtable(); + + _fieldsCustomProperties.Add("ThreadLastPostingDate", fieldHashtable); + } + + + /// Initialize the datastructures. + /// flag for the internal used relations object + protected override void InitClass(bool obeyWeakRelations) + { + + _columnThreadID = new DataColumn("ThreadID", typeof(System.Int32), null, MappingType.Element); + _columnThreadID.ReadOnly = true; + _columnThreadID.Caption = @"ThreadID"; + this.Columns.Add(_columnThreadID); + + _columnSubject = new DataColumn("Subject", typeof(System.String), null, MappingType.Element); + _columnSubject.ReadOnly = true; + _columnSubject.Caption = @"Subject"; + this.Columns.Add(_columnSubject); + + _columnForumName = new DataColumn("ForumName", typeof(System.String), null, MappingType.Element); + _columnForumName.ReadOnly = true; + _columnForumName.Caption = @"ForumName"; + this.Columns.Add(_columnForumName); + + _columnSectionName = new DataColumn("SectionName", typeof(System.String), null, MappingType.Element); + _columnSectionName.ReadOnly = true; + _columnSectionName.Caption = @"SectionName"; + this.Columns.Add(_columnSectionName); + + _columnThreadLastPostingDate = new DataColumn("ThreadLastPostingDate", typeof(System.DateTime), null, MappingType.Element); + _columnThreadLastPostingDate.ReadOnly = true; + _columnThreadLastPostingDate.Caption = @"ThreadLastPostingDate"; + this.Columns.Add(_columnThreadLastPostingDate); + + // __LLBLGENPRO_USER_CODE_REGION_START InitClass + // __LLBLGENPRO_USER_CODE_REGION_END + base.ObeyWeakRelations = obeyWeakRelations; + OnInitialized(); + } + + + /// Initializes the members, after a clone action. + private void InitMembers() + { + _columnThreadID = this.Columns["ThreadID"]; + _columnSubject = this.Columns["Subject"]; + _columnForumName = this.Columns["ForumName"]; + _columnSectionName = this.Columns["SectionName"]; + _columnThreadLastPostingDate = this.Columns["ThreadLastPostingDate"]; + + // __LLBLGENPRO_USER_CODE_REGION_START InitMembers + // __LLBLGENPRO_USER_CODE_REGION_END + OnInitialized(); + } + + + /// Return the type of the typed datarow + /// returns the requested type + protected override Type GetRowType() + { + return typeof(SearchResultRow); + } + + + /// Clones this instance. + /// A clone of this instance + public override DataTable Clone() + { + SearchResultTypedList cloneToReturn = ((SearchResultTypedList)(base.Clone())); + cloneToReturn.InitMembers(); + return cloneToReturn; + } + +#if !CF + /// Creates a new instance of the DataTable class. + /// a new instance of a datatable with this schema. + protected override DataTable CreateInstance() + { + return new SearchResultTypedList(); + } +#endif + + #region Class Property Declarations + /// Returns the amount of rows in this typed list. + [System.ComponentModel.Browsable(false)] + public override int Count + { + get + { + return this.Rows.Count; + } + } + + /// The custom properties for this TypedList type. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Hashtable CustomProperties + { + get { return _customProperties;} + } + + /// The custom properties for the type of this TypedList instance. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [System.ComponentModel.Browsable(false)] + public virtual Hashtable CustomPropertiesOfType + { + get { return SearchResultTypedList.CustomProperties;} + } + + /// The custom properties for the fields of this TypedList type. The returned Hashtable contains per fieldname a hashtable of name-value + /// pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + public static Hashtable FieldsCustomProperties + { + get { return _fieldsCustomProperties;} + } + + /// The custom properties for the fields of the type of this TypedList instance. The returned Hashtable contains per fieldname a hashtable of name-value + /// pairs. + /// The data returned from this property should be considered read-only: it is not thread safe to alter this data at runtime. + [System.ComponentModel.Browsable(false)] + public virtual Hashtable FieldsCustomPropertiesOfType + { + get { return SearchResultTypedList.FieldsCustomProperties;} + } + + /// Indexer of this strong typed list + public SearchResultRow this[int index] + { + get + { + return ((SearchResultRow)(this.Rows[index])); + } + } + + + /// Returns the column object belonging to the TypedList field ThreadID + internal DataColumn ThreadIDColumn + { + get { return _columnThreadID; } + } + + /// Returns the column object belonging to the TypedList field Subject + internal DataColumn SubjectColumn + { + get { return _columnSubject; } + } + + /// Returns the column object belonging to the TypedList field ForumName + internal DataColumn ForumNameColumn + { + get { return _columnForumName; } + } + + /// Returns the column object belonging to the TypedList field SectionName + internal DataColumn SectionNameColumn + { + get { return _columnSectionName; } + } + + /// Returns the column object belonging to the TypedList field ThreadLastPostingDate + internal DataColumn ThreadLastPostingDateColumn + { + get { return _columnThreadLastPostingDate; } + } + + + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalColumnProperties + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Custom TypedList code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomTypedListCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + + #region Included Code + + #endregion + } + + + /// Typed datarow for the typed datatable SearchResult + public partial class SearchResultRow : DataRow + // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfacesRow + // __LLBLGENPRO_USER_CODE_REGION_END + { + #region Class Member Declarations + private SearchResultTypedList _parent; + #endregion + + /// CTor + /// Row builder object to use when building this row + protected internal SearchResultRow(DataRowBuilder rowBuilder) : base(rowBuilder) + { + _parent = ((SearchResultTypedList)(this.Table)); + } + + + #region Class Property Declarations + + /// Gets / sets the value of the TypedList field ThreadID

+ ///
+ /// Mapped on: Thread.ThreadID + public System.Int32 ThreadID + { + get + { + if(IsThreadIDNull()) + { + // return default value for this type. + return (System.Int32)TypeDefaultValue.GetDefaultValue(typeof(System.Int32)); + } + else + { + return (System.Int32)this[_parent.ThreadIDColumn]; + } + } + set + { + this[_parent.ThreadIDColumn] = value; + } + } + + /// Returns true if the TypedList field ThreadID is NULL, false otherwise. + public bool IsThreadIDNull() + { + return IsNull(_parent.ThreadIDColumn); + } + + /// Sets the TypedList field ThreadID to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetThreadIDNull() + { + this[_parent.ThreadIDColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field Subject

+ ///
+ /// Mapped on: Thread.Subject + public System.String Subject + { + get + { + if(IsSubjectNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.SubjectColumn]; + } + } + set + { + this[_parent.SubjectColumn] = value; + } + } + + /// Returns true if the TypedList field Subject is NULL, false otherwise. + public bool IsSubjectNull() + { + return IsNull(_parent.SubjectColumn); + } + + /// Sets the TypedList field Subject to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetSubjectNull() + { + this[_parent.SubjectColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field ForumName

+ ///
+ /// Mapped on: Forum.ForumName + public System.String ForumName + { + get + { + if(IsForumNameNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.ForumNameColumn]; + } + } + set + { + this[_parent.ForumNameColumn] = value; + } + } + + /// Returns true if the TypedList field ForumName is NULL, false otherwise. + public bool IsForumNameNull() + { + return IsNull(_parent.ForumNameColumn); + } + + /// Sets the TypedList field ForumName to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetForumNameNull() + { + this[_parent.ForumNameColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field SectionName

+ ///
+ /// Mapped on: Section.SectionName + public System.String SectionName + { + get + { + if(IsSectionNameNull()) + { + // return default value for this type. + return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String)); + } + else + { + return (System.String)this[_parent.SectionNameColumn]; + } + } + set + { + this[_parent.SectionNameColumn] = value; + } + } + + /// Returns true if the TypedList field SectionName is NULL, false otherwise. + public bool IsSectionNameNull() + { + return IsNull(_parent.SectionNameColumn); + } + + /// Sets the TypedList field SectionName to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetSectionNameNull() + { + this[_parent.SectionNameColumn] = System.Convert.DBNull; + } + + + + /// Gets / sets the value of the TypedList field ThreadLastPostingDate

+ ///
+ /// Mapped on: Thread.ThreadLastPostingDate + public System.DateTime ThreadLastPostingDate + { + get + { + if(IsThreadLastPostingDateNull()) + { + // return default value for this type. + return (System.DateTime)TypeDefaultValue.GetDefaultValue(typeof(System.DateTime)); + } + else + { + return (System.DateTime)this[_parent.ThreadLastPostingDateColumn]; + } + } + set + { + this[_parent.ThreadLastPostingDateColumn] = value; + } + } + + /// Returns true if the TypedList field ThreadLastPostingDate is NULL, false otherwise. + public bool IsThreadLastPostingDateNull() + { + return IsNull(_parent.ThreadLastPostingDateColumn); + } + + /// Sets the TypedList field ThreadLastPostingDate to NULL. Not recommended; a typed list should be used as a readonly object. + public void SetThreadLastPostingDateNull() + { + this[_parent.ThreadLastPostingDateColumn] = System.Convert.DBNull; + } + + + #endregion + + #region Custom Typed List Row Code + + // __LLBLGENPRO_USER_CODE_REGION_START CustomTypedListRowCode + // __LLBLGENPRO_USER_CODE_REGION_END + #endregion + } +} diff --git a/Docs/HnD Administration Guide.doc b/Docs/HnD Administration Guide.doc new file mode 100644 index 0000000000000000000000000000000000000000..e8530ddc5da7392568284bc645c4031622174f3f GIT binary patch literal 67072 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 AWB>pF literal 0 HcmV?d00001 diff --git a/Docs/HnD Developer Guide.doc b/Docs/HnD Developer Guide.doc new file mode 100644 index 0000000000000000000000000000000000000000..b0c77d77743e8280dc680187fc521989ec071e9c GIT binary patch literal 53760 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
ixRc+YT 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 bMUwO_c%7m@$A`gA4EX!J^Cjy4P`>{UL!I`N literal 0 HcmV?d00001 diff --git a/Docs/HnD Installation Guide.doc b/Docs/HnD Installation Guide.doc new file mode 100644 index 0000000000000000000000000000000000000000..43d3cdcf079cf1c2d7c3072a365e7ab79933775e GIT binary patch literal 220160 zcmeFa1wd3=+b_Pc18lK%L@Wdp6a$k|5fCLzJUTD~3^9WfAa-|mcXxLk>)0J&cVTyX zf6rQb&ul=>@qOR#{_pp{_d_3ct-a#u^{i)Y&YmfJd%=d%cZ3W-O@!>ikDqykT(bK) zaK6k+yirIHR^ps4fBgLUlkP6U#bUq`z)}Ei|Ig2Va|}FN@~6tGj`k?m9gQx;i$xm?!WUd`#rwsnf($`2d%trojW4VE zsNN%}XmcGw82>vJ{$`ozy1bx-CyC$IcROBULh)n36#tR<%EOLdd%FpOoKJfL4|IJ8 z$67cN|Itqelq-Z6q2~(tW9Y={l=p#&)D@3D44XR!6B`iM|<+|MWa#`TweGiC$UtJFELr zfB)5ER`ro?&TB0QwaY_af=_Y^Mev&}%K!ZQ_s2j>t+&EgYcML~;*>^>POE5P(x}un zZS?9$WrW&Be5BDvDNxc;krb_oh*oF}3PZF`Z&XC;^oo}1xCDh#t5SGt3=t-S!I2&- z6$YbTsfmhaWs;P7l_Ei}i%=U3iX@FO8qXtiri3`PLKmqpXyWP2U{og z3D;o*8d0ee;&jRJYORs_OV1*7@d=tZwMv0*8;BU<{a^IL zQ30GO4QfS#DLhVN;Jr;!hZ{6T+|%n~)DcF7GEu3CQ-%Y%8ZB#psO@Zs(<&m-j3QF6 zi&wM@c5dwxqHwKM%MGQBI-pCTj!!TqgSc@jwcb%-LMyy?S|d8kuxpG~5@o3XV}f5I z0XzZ50-I#Q1>*s_E51kF0n?=KE?STV$6Ioi*pYK8V>4rt&M6_9A%gRlyG^7;z3Y_#yAme5mqo-y-Dk+ut8U}?2QPWHc}I10*6uWEbmZl$_U248VsBe zrvw*-E5h}$FvGxSlVNdyC{7zvVejtZR?1R|^uqp6h;C)R%&oT3dI ziK`=8H?wMz2E3-z#(~8|rWNt2F=~`?;2GXyjuR$CG_EK$N4q!#PFWhQmSh=ZF^XKM zR79GHnN{%`Epa)ohe?T<#|&zY4`LsW^aYu^aJC6jcQXGg0*MyrzsFP?p|1>u4MxOSGXyF z(P$_g(1UT9M{padfTdy^4^Bta304md2x+6>wb{_{!0e>GR7#@~S_LwKDmCDFy5Y!F z33Vg_Z<1J8luSKG5}{h`x0|EFr$>UGlpWp<2=?}YTGJ`Qp~Xb5GpLn%5MCS)+AzgC zGSx=-&?(efRetMoQ? zMHg;VVjN^Jpsx*JIfh$^P3yoAA9sasBtrxw(3B9RSE`69n7k#rI@h8KaCBkFGWQ#u zW_%Ic)?YztJ;4ZM;9b(zUGY{|qYeibXG3=qBvv#6 z6aR7*8Lo_oH6`%QMVRz@vP2SMfM{q2vJzlnm6|aUWRpy>g{(d>2>JxQ1_+E-YL!ty z6iNpN2Lv3YMJRpZt@u`W_SZC75t=9N5ayOY{FGcQcvV6FG8<|Ng}_HOD0I@MYpIm z^G&iWD&hhSUQMrm!Mjw?eWkwgfSU^9$)98dsCpEsi(ot^pN{M%Vym;pu&{W-6vsbXhfl=hR&&AasM+g%4kp zV+nC^R$&N?8VEkw1!&dCNHx<%)TJmr<_V10a3*zeYPb_5VIw_ zKr-DrSP1mOU?jGssyxhNQ!pk4o|>a^bewyZzGJ_d1e zrGnmcW?l>w0njO$18;ACg~c>VeglmShL}%E%!)&fFPeRT_ZWhB%Z`dReiMn2U`=`u zM>WSKV=_V_sXB~`VO7>65>(i`WRfp;Rv8n2xUP&P(zVFuh%^jn`L4cPKhcyB+9y-B zbdNIxYk=sfHo}}ySJJgWLV&{QgpKP)SExBi0#`lso(#csY3T$_sUp8Ql_FSDk={p;SLkn z2uzk?o6ULyDv3<3IBAr*GBGB&Q+zxsMYRwNfs~pkY1O&^8mCi|C&0|H=yWq~WKI^{ zr&r{zjXPs0ZoI?5NWsj-GK7(PD$=Mc-XZtO#uM}>@=-koH6+Lg+DnqoDU zG8w&vxs*w35_v*_et1V62?vEwu4R~%Bv)()twfWR!1#VWARg6_m+CAn?V^EjO@7ECVrHgTF*!mP&NZewNBTodIkr!KQSi5l27Zt>H}6;Msx7d3%1 z_z_H^)}kBWK=@n;2+)+4d2Xa$E$qzL)y4yT1|qrghtI?(up$G>`)(teqa-CT2;K(& zioAv?4v0b182LXsG;fhNlDP`bf^6Ot2}gps zQba=%e_N-IWx9(^u$6I1%4BlJP*AJDL?aqnK}DWqu-eG&d4hsCp7)bav1~lVm=04s zsGWMDkPU=5*$_uzFq*!b4Vy@Gnfn|dxzF;z6)6%H69UHBe3{V)&7>!fXxJ_K&7ekn z0p3(xva^k)%S>r=#{{-Pt0O-kNvBs~2;jX~4bz;s$2fr)nw5p;$4wV|-C5C|qIbkg zWZ0RfA+L#s8?8x5P^-vDFyc{JQFpWm^$qh#Na*SfjTOdTb2egfOWMa-(NQ+7Hd|TN zH5NjWrZ$<{Bzb`mN;l2XDPq;|S&0M8CR}9J^vzNy4awRFZYnv)WEvFo&qR<_6exPd zjDI$-Cq_}klPi&F>W~gMviHo96?D%)w%=SMhT;jSHz)$NahPv2XNP-+26*n~m?p6X zh?`MV5r3fGri&tw`Ll%K+JlaWSV=L0YJmt)WC$EM!c-<;!btQNr^|uC3S)ADx+e4` zi%U`?7%$j|DPWzpI=F#F8zgHj#U9v%E`n5sNC0Jo(FEIX=0@Bm;|DUz@WaB9Fjoo# zyjqHKiM6vJLpU@S-Z$!XDidrnLs4e&$E*mw#B_l)g%ofS11oT&F=@;&2*zRQFzg2D zhmjCp$|Tz&ZUVS}&3y-^P(qmQ;5QtJ`C(=mGxAervRJU&CJ=ZwONrTPX%)ZF3`9mf z3#doL(cFZXHFMM4+{qM`FS%-p5H|C2YNGI_$rrfFtfwq=Am5vrC>k{?Ptx?HusxIm zo3Z`FOPs~v67t@)hRSBTlUxAS*EW8f=8lSx=3T{(cg0N_m*pL>G$JJtx;RrjTvK8j zn)hf?ZM0e(G&>8|^&mlnu7aHb3yBr7U|ISaC7U6|UzoNRonQ0Bh3Zmj5%h;!6{plj znJ{5OuQ65dflrI@x@GPlVi?h1=uU)x)!=a1OQ->QfUgh$0o)vtKq})%Pb34$7UYXz zJsIH>;;`z%IGX4yb2%I#0wONqt00DqfD?6>P3O{0Ybm}AZyQ<_3WNfxXp&7%2`^M@ zoDL1r>OvChENOr9M99)N#u)HZ8M849%=`*k${|f8+6(5is7$OS3TmU9ItBMa%`e*U zI-0{NH$(#`LBz#QoaPb-E2A(M;r{7Av9K4&Le$YCCWHb0r`3ffK>g5+f#d|pqEHh} zI<=V9F$K$|nS8+nxDmh=MNga>SWJdRswE4Lbpm&2SVk{!JFkH;y8$yO-jGtV`x%L^(En%s?WuvkRt^Jb!ZGM9ezdbmRsBvs1Fz;sl8*;hv0H0hnhO z(tM3tw3HKhm4f21Cp^NO-me0_Lhy=tDwECwm4Zmr4fAZ1`bkQfIFpVvH)j(qG{My| zA=?!dXVA-;Egxd;q|g7x@=c&Qa4=gpVEU1{Y21&SDA|{P-+KKYG8E=m>%VOpvNQ_L zB0c}d4*bV<0CNbY3p`9lT|9Iz1sszVaIs0unIeOIBdx}RDO@#*CiMUR79_Lf#;7UM z4{IdO@Ze$a5LjllBpFB26{L}5Ht~Opbt0eo*DAmM|ETI1^D~Hi;A`ASUL0R@CLeA!;Ox*%h;d@yzw-4h9^$ zIE~R52Op56Lfu2j5@;+_8gc04{!vSC^`vPZ3n_3TC)mPIoW6K>*4 zoCS+K>F1XdHKmj~B9Bx`zCO)Ov5UL370pj{mc7NO%bn_;)5sV&ndIu(W@c_3`r z@|UwVSrC}}&K8$L3UndHK{Gzei-AK%h!L+uUq`P<)acm^ScQCv2sqx!&WZpE9o z9L#WZI?36lwa%zEuh9`DdA^C9>+yz?r^q0HA>~96tKzPdY{f86OY;~xmTWK`rkNdR z#^&U>sZ7*quue(QXqw0(s*MF36V|YjG2Jx8A_C?ihQ`EI_Kae}*SW+{HLF?~7q3Gc zT8ni_J(6Frh(l`yV)W9o-a+$_I0bSvDE|of(>pV6m9i4Vby2b76adC3f;$F>_ykZ~ zoln*%+r!D+3af=AoOzP;ie(W_tJBA$Ip8)!d8r50I<#?2FDDdqQ0rL~A6;x8804o2 z_6cg|>*b@UCKIUI%zLDQoxX@X0fM8Q1+(hn5XY`l=+K({RQ z6H5TqtdA^e0C81H!eZt!XPZDCxG>-0@*@VeS>goM`K!DziuW;oqyh=i$;jP9PxU&) zqD5K3@GvyKswQc-2=_2VE{w zCS}QqmH^3z$Yd15)ha}rkl{dL4T+?pgdE1GAP%?=DNc|}1Xfv|;xF>@Nc`f}Vs#KW zsskoStb$FCY1n48NthM266>OvYeQABxfpYO#J(h$^a)tEl{B3>2F`}X6aw#}$dmF} z5qB{esl|?C{Y*@01fhTxo?t-&4*kI z!&%Xa*1{~24Y4q64ZSKd8r8^F5iokLASr<_BwYcD{ZgQlt4;BJ3;lp0s?ehMF+}+) z7%4WhijirJTEtG?m=0*P6pf-Z7X(-3%I5EN4e4}7nhZ)pR4DBwyDW}Wlo?JE^jVp1 zDncWOz|04MZMnlZ%#P0W+XWU{GBdc@5O%Q19u?g8wX1G>JHj{<##ur{iqNgsrh94}<#QJxde zma>E@fjyRi3TMS^$+d7xM4w62t1JnGutkrc^Bd;u?A># znaihd2d04u8nFaV3Zu0v7B^O9e%V>U!g*o{H*?+87crvO8f%k?He@VgPM(m;Q75Gd zp{UOJnAl(@2otCGk%_bk@I@u81p3KYo?6aCYiAoitDuKU znM+I6Sk@y%1j(lt#HsAIWMDH@OCLR>BLCfBv-ICtTWQQr| z>6dKu3v7|3lS7D6qeYqIo0kWf8;@qqvnB@E<SHBG*=Olf~r#<~{Q14%bPdCnh>g;U-O- zitwAUCy-p~vCR3g@iK?|j5;jACsC#$mhPa5VX!Rrjyl9HdA176z%j27bz~MUiF+2x z%qkgb#GJ9o1K(`Y%=(fA^UFCKEF@!INQIbxNcNkv6V^c$nYh`JCeSR`h$}w1^^w`B zbOd2s3wMiSPD2C%5ik*x7D^|0!HF}fC$aZ_zggZKbh^_;Xeo60jb|ax$rXEP`^ZA$p>v_ywGTc(`~Z zk0KX<-sWi`A<(P_;P;3T1?UepHJ4R__zjr7a;M<|3hhq+3$>jW!xMyVa`aS`V*^ zVHj=zc`^at4MTpvGTf}GqaX=f7&7qnFn4$4seG+Y_vK~Te(9Yc>(W=B}Ol+NJ{_cJU~k1!ogU&1WI3UkKV4pSA3 z8`&(4+hd|M%>&HCVqtnIAD>p&GViBhLxb8iU~dx>V0uw-6A;@YsRds?$pSc~WG=Eis@ zMKet%;O{pfNPUzXNP5E@l;yK^1eFLQ=00NNVuk_V`2_|8gMh3^=;8hWI?S;II+2${ z4yCv)iEUsbcETemUqakK#uO&Y#FCi~Rt(`nn%qEzK$zH^iCSU^qyCBu2BIYtQ<yQuA`+3zn=+(MX5tia9SnRGl973( zB{K773XWDOdl=-9X2zM4sAU<>=q5x7nidDXwUFm!*?6c}Di{SaSlCYVsR(P9xCl{4 zLMY3sW}1WOCF3t1ub}r>Ae73ZF*HnXryqqV)s#pmjsthn?>>@6wZ++~IfViBu?>1G z3Pqhj8^G+ZGOm%*$mUrXo+S&9Sdz!UX_U~==D@J!0r&DU@(5#mmXwpk_Ia_)GsGBy zJDrvj6@8K6MAj{(tOIQPTDaNLm}vULqKGsW!WUZR9-Fg5K{NuMXjco1H=&3nV}b`M zd@LJeq-0ZB);g^V@pN_Cyp{fe8#bbNik=TD7A>cxeynN(-L$IBf*fR0nMt9Z@L-xs zoHa=dBIP#&4ImCz;}ZEvE5Xi4sVruV>Vi$C8PeZE8Ar0Y3HQhdEktdpF1(z1*qAyZ zjw`E*SHo)vmgt^kh31S45f2pApc){U9-Jj;+)M+B8DHX1;6BqvcUoUDC&jU%;)v7b z?i1TF2_pB3L@T^&x}<;ED52r0U8p>%VYZTh3!WOu9*G#?({Y~vEa?PV<&nM5Cs%xl z0*GQ84MlYhKZYXrz$#boVx>^+9m%g_{7zeIhyxI*V)IHi)|y?~Ew@tX9IjMKSZ> zAF^pFu*gwKa{|7Ro3R3XdiGregqFpr7fcYkhCMpWQiEfCdVt@_sRptv-Q!Vn`4%3Q z6P{sj1Bp>)>B^uxxKferF37A}LeO?5yJTJmqiGFgvttj0TFU@#@nicd3H7;GZeBp^SG^(C>$*d@knG!GG1 z%hJ(;SVra-5jq))#V-he`K00!V=-L`_gjo+NF0UfGI1}w70e67`49~e7f$fbqWG+i z72z{LHg52!^j!{WT53ya*{ZLDe&Q%%R+Gq$z#`1IN->EQo2;lt?k#P7r7F6cu*?OQ z4&foSo@N9{@WwI=+e<2GXudmDiYL+JQh_fQWD4$+$q?fP@=&3_brMp^a}=N@Th1gp#)NM=WLAFuVn&R$m zDeh0MDs(p`sG)OIJBhZ%moaZ$=Pm#hV3K2AKg#LwD{>L;xRDd5aMT@3U+F624oYB=h6o*Q!ZI~uFBa2D0OfcODQ*KloePRl86`UNmJqO6l``Lm zO8mN`&R8L3nRApfL8D{{5M>C>skOvqz%=Uvg|b;6@Qa4;o}c<@)5sug$`WO&HGGvo zkyF%$CN_B+(V9@KI=QhOsBWi7RK}UqjqN%j#3FmcPEoUoO{1FsR2gBUIenFZ_9JBK zG*dh92JvAj+D4M0i3}`gUe4jFz)_)gjzTJ0a&wB}SUeLTMGFOkji|KRj6wfX7qb|z zSn+R;6DlE?XYyE-CJ5onZIJw_7!Tv?F_=e)i*|`hy+#e)hf#{^-mH7MrX>w5?jPs* zI^>6t@Jcg&x=znY+1Kx43b+44bMNi!z?J*-qaO}Ynwa3l)v~bCqyWC zzFzkVCV~A88v1##wtJ-wv>}EYS~{T`e}UN=^t5qIAC5BHA)X-Oz#4VzD-2Og;!%W9d@!eOx;7_g$`;!g zbEJ3L%&TlH8HEu69bgj_iW>1X3ue%XtJrJLn_3$3jH$)}z2JHf8Ut+TiO6t0pp~+qovBZr0Hl=@EHmeWQg3qH2d##5>FqFD_@F+D1n6ta#< zwLm1{zoBR{Sd*dx=vFueO*`;`_5|8MXqHY&xMYC?TFbXk?5Rd zAkc}NI7}(QB_mT#oQviqDp|O4W@AVhC?_Fn)3EAaxf}* zpCP=Bs6WI#ap`-FS6NOX>xsNx-Ua5JniD1DqakBP&bKL&r(Kc9lNipk$^(BP$ zthG#v|G8I06~d()Nf;($H_BT=*C}C!;0 zJw2tZx_YJ70DQ%F2==EAQcsC5Gk3Hmb%wEQH5P}Wj-(qK0@s|EoqHI_0YHEYV*>)| z022aDPw_l!82MRyOoo( zI$lLHEsgO=Dx>iQYocJ(@VSYQEJp~p6A>)1ijErn2ZSi_*-`X`?G^jm!BC%BC*|VC zA}`20pfCxvNKIPDG)O%p%P#iaCP3N41IzDPqu3oo8@0X-#?9#wuk4|ThwfIgB7|=d zE#O~K-C2ay>^0G{B0c784?V&Z8FPTmDuoF$b)6N0ilE4jR0C-VJYsLiK7Zid)`#>o zT!(Oc1=g4xfQb$7r^P`am1r)2T`So1;f(KkG?p!l;G2yu>29#yG1WvX4By5z<5PSQ zpgp2wU=}z7xS7%Ee2zaHYTI*yo)Qr=F z>#@bBW>Rf8H)Vr5u`J7n0tuun;cUphhDsg7$lxofG4s_U1w;A@tR-tu3ZYXNn~{|I zC~~PG-k2ayHKlc2M6ub&G09!y#oTQ$q2&G`+M&sEMa=y}Pz~n=GsaOpo8Yh(L8VcQVWdpFKBi_Y6fPI_GPrlmTm9V}Pj;}dY1=>tqUX*CVY#O#}~ z{CmPCvJD6%;0w7#LgcBW+wH(w%G-#LVXiKK)z;WfM64aPow;%LN;EkM(A@IxO=CGx z1?L^(R!SP%xw`Qy(TpQy zP3l2oJEPvD=1s3m zvs9S+<$PqxO^gIyI7Tw}mMIfH)#W=#sH4oYAT1;H5W+5xq`{0w0I_n#Xz5*g;DKZNdrUe#x?X>%w$R@rC`$7|6a35?2*$u@1pv-9}f;oV02^`8|a%73b zI@l=1030o!fjQXbO{uBKI3+xL8CPLWL0ur0PiG4lUn#lXrI%sJq3(#;M8SthGjEIT zP+B0|L4+)t<5KjUm~@C=Lqzo;Ogc=!0C76Er|lP_a+M=m`e=$JR4&f*8PR0%SZSVX z#ykrH(TGG^!2(ES#CaK6Y)teBZKA&5^EJ_uGjvEX9$*W)2D2;C(S&7`)@~@2A{k7} zUNUjo&27IqKMb5j6GP19__x$Vmr0tVi!JjRE3NDz_968ELm}UoVi5F&En2KZzL9xB zmpx|TKURcYGCm;VM4#0FjoGvV48ha}p~eH>;tHX94InDpvMLUbkdh%Y(pj}NL=VKkFq6kv(yv0{7G&l{QD>j2hGzSGx$wVd$2!#_`WG?8qBT4 zdI)@lIJnM6td5Fb_U22rYW@Kg^Q$6m#4nqQm1`h^NV1f6@1aWk2R}o?jG!$yc3^IJ zxy(Bt-9SrPeCsfkNewtjZxwPiCd^`2tC@xCvW+57tsJMz7wIMwFWiSfsdrCd$1q?LJ+zLG09-lYzan)t;q(wjcX zuVGHxFD#=CHlWF~hRnDi4hQOqCH18C(iP)QJ`;YON@1JSr92 z^=C=BMrri|)$W6wf!w1gb;2NCsL$DRJ+{!*?&6a9l z9`GSvFi5a@IbNKKVRpfvG38G5W}kQ`i50nsgn?KQi@KIH1o8Wvj3F2n38#En0uddA zGofrMGRIkt4=MSJrnIOISvh2UMI1RR0%;>$=D)4L|IPw+ftthA0aJS7W=SKJ_Vm)KUXn)p5^> z)n?NgACV(Lf-YsLGx??1n>$Y-vTR}n$`SQo2$NhSFoBpC0_|r`3W1V0Gl#Ul0X&b@ zW9B7@a!T7mc={b&BL3|s+0JBh3nUb*XE2()2}&-vC@-E>$84I26>|nM*2XC12{R5% zg`=eGDB>N4FDMmaI9`Nj)YJ9>79+G+aKa(m7DN2@tBI+|{Yn*umk`wzJt*u%f-?%N zi@BJzluVy1RME~WDN<>fDvRz3{e1}58WQQLK_7C6Gt7i(7KT9?F(JWF%vH(KK51OU zLt-Vo*GfG;!T@~=d?F5M2`s};resdMg8uQMs8);}ndiq!OAe8l{b)9?%r~>#ae1I!}mw;jTlaLbu-vHSP;XWV* zkfX35yaBugl*C^cD+O=|OaM#=%ml0je#7srw*s`e|vUp+_47#Hl9meidzfkES#}$GGIpPjB)rY zX13AoG!q23JOgm{&T$%@<>L3~8QrPN?$DWFT|9bAK(t`Xe$(@%<$ur{xKC&NTEP2s zB@~q3<@LI{oEGSL?S{_m*r?-Kc6?rbD?8pQ)PWtT6)NW*Qib*Llhr1%XLKeMD;`Zp z+vw!5DuP$5`hpT*xl7NayY=bsd=l*|0G91Fsf8LwVaPsQ+E*{H^rMt+wf_w6JZptq%|K7zpd9jo7i@)R->53i5^2weo zp9nd!3sEX!FCj-ZoH3&2u)-N5cMdz8F-E~((&JA-o_tk={LQH}V-@y)(qSJYRP(lzYmlT9Rz*oRF{1Mk3fGVX0p$)*Uj36`t+y<;ECkT50 z3j77tz5rW=Ap8Ls59nG^5bEJCRjL36K-N5vjv=0*2j-u2Pk!^_k@;<$q`SB)e{v(s zixl~j3t3*AkU#may^z%`QIR;Lt_`jjr56}taFzr2ta@}7@9{G#$Db0l*IR?{@lxTz zXR~z!M5!EVjTFmselv4k3DS>5`&IxyKnFl9fOw%Mpdp|&pflhLfOw-7_+l7fBw#Cm zcx5|)_~iqjGWdn~CJ;cplLQz67zx-3I0dK(J|doS0n`RG2HXM=e<{nN4*-eJ_JGF@ z0g5XuyfzN!#BX+$1fd#WAYcR_6>uAH2XGhg?bAE_d->_{r~9Ao-@bPH{)O8o4xZSz zYul!E_(#82EnYQm)uwebaXoe2)Cu%&%v2x+`ZdKPfa%xx>hDB7PiLgri73$gI3oh! z3_709_%*%D2!kUdAC8PXIBu`y8gxc2w$9&{*&rgeZ8Re}%F&VAD3f*=E61LoJh4JOlFPRwfcKosLxnVFBP$HQ4Lw;4#1@fQJKYGT<~|tfL^zaKc|;t_fd) z`YrvuluqcF?#Wa6lXMpkvV4-RSk{95zwt?myl?4r2JE=yC*6~D7so7xEN3|?LWU>D zzlOw;rson)a&0*yW`ck-Ye4#dF=__QK=-6FB=5w!@@vMJB}hh6K;v5gHRu`-=n0qy z2nUV#0*ZsaWdJn*jsO#&H{c}T0-zaaPV|@PJ`=Q`1DFf&2M>G)`~VO?G^iyA`vFG) zUjf}+1wju8tt|+X0Sf_z>%gxBGy}A*3!4JSQ4jY4MF6D$r2%n(cz_XL0?=RBz6Q7s z$WdPqastW#DgYFKxqxpUzrB6&_S;)J0zQ6w`u5?S>vtZeoO^gG<$B7olw+q3oZ6eR zcgNl>8>D|r=PjK#ZRrM32tM14db1#1^qYHjmTRFnmr{8d$SNd_%8-Os4oc$wT6Bsi zlb>)#e&e*JO;IcTrgHslpR*&ow$2-qU1;^nHkz>np0Xn(n@XV%IGe7`E$RX~qZ$}- z@q}20OFv^C+#$B$cj&C4oF+sEgGdXa0pUN;jpN=PIGqRlJ!=5%?tgL$P~Y zuaG`qPfL(Y5M676u1x{YLDv_6QlM>VKs`WxfIlDz&;!s5&>t`oKs;~`^v?#`TLTIJ zh!;u&Y5;x!a)Tc_1L6SjfLDNz0OFA<06n0e$S*sZ!AAge^1wTQFhCc;aKH$_T2Ddv z3sBYz^#j%eHUKsPHUaFs1)&n49pKxiSDzl-#J^9e_;=~krE@1S0X&I+hv?Tnz^-$< zHlJI+ddaRiyJqZ~vTOB(F%u**K#I=AL#yFfy~aLv)YS&l;`)+}p6P-mZHGc?={NTP z$Z@xgmS$_xky(7mxTQ4JL09BS5Sbyx&@6PuuTh)$gi9(tp?4U`@Z?|6KIt?TuT8Fv z>XM8Sz6sZa-=o0oa1oah9{=(Ygw@T#11;d+wS-Ra6@)~<55T2Xps$}Gob`vk2mmbs zZ397Hz!wRXbWG>Rr<47x1t)89|92!jYejHg-qBP4>BUib1qZXdkU!x5J!30o^A|=( zK$=OeW6LW=x#nkdkFg_@b$&+o7^|{(8Dp_`Ewet$J$^>=&(3T~PCP(YUy-)0K~th{ zKhU%YXju_JbnOlx+U^8hKL851fn9~aSr3o|=n0q{1RoJF2QVM70MIBH^#j%cHUV5h z1i=;11`q;h59k2s30pWlsKr}!DNB}Uq{q|+r%e1#?kJ299#lPc^j;B33 zz7dC+_&4yl4*%#k5M0?d+Cv-1{OG_|IfS-=t}U%{kdGbTQplkNnDSUT^HQD;xya$p zs$fF&Pt=Iwg1NlS-2GE85oeoH+5Yk;d0^ZC&|Fsu)&Gq8shWsMklS}d^Sznxz7yFMdBs*(BZdx(J}2`TLCAOxo$J0EAZcO0W`&Erw{?3-#@VmiBnxQi|&snlrGo z5+qaI0ZD)<0HW_|0MYnQz)^rpD5v*499IK~?r#92L3^VA62Mo$HvsWM89-Tp4fa5uf0!S*v$q89Jk9L=@D5(u_Pfmd*z0g5@Xla~Y*RF=G7NI^;KX!tZH5 zp(^2++7R7(gr_8PF5Z3osDy?cGc9f7-okX&25MJ+prL`u-wBuMb^My8J+m zz#@Px#PcI0)clk6#Y=M;oII6ZJjn9miu}p{1s7S5G)w)?m?Q`Jf&7g0 zJDtgG2r-2GnyI!@BzuDZqX91g9|1(y?4Vn2KpsF|Kq&yxx&ojQz#dQ;P!&M*cLFp8 zGy`}5d;r7~et=*=2p|;D5kP#>6%Yl82511?0mM6f0RsWU0FwaI01E&M0V}{qeIwzU z0;)toZvhejWFr<|9DVT_{$=%hF-k1HIDGK%!Tkrz`9;#wINs~y&1?okA@nmH|8+g` zuj++=Rqyaw)^Pq{>o_}Y^-#+sIsA-P`RGiN>)g0zY|P5=Gtvc?d+GIqU`zB) z1oQ<2g6>3nl}P`=A`eUeAAAPfh!uqU0OARy$QQ-H6U70I0ZjlM0389@!6SJ9#Q?-J z5r7!LZ1BZqz*zwC&v^jx&m{oyPYQte=NjM!;3nV};5Oh6;4a`E;6C61;341<;4$C{ z;3*&t@a6sM=kH(BzbAK|+<1+(|4Sz?-S`Xt4&2yzW7Dc-{NJK^mVe7OWgy8vUqWk) zYIL4y4Mr?nFRXx3n%8USDm0H3tU8g&mi;DcZn@&I9=f)i!J-!`9{t9{Mtq}It6H); zsVwS5TXaUXeGht$lJuL;0qKl<2T7wbKNKD+9Z@&V=n2jQH5Epz?Yw5wAa#tt7yD{Gn|Buc7Y$=JAgA&n9>aDshOgBeEZ-f_p1H&i**N z?A9+&3ko@2AsirV%#rUE)nEl)6Y>dymyrLJD^7EGka5fTXKDP-Wku}s6F2e*Ed?#w z_7=hgUz`~Pqo5Sx@Q;29y`oC+(?3Ya{pz7#HX&zDZCl&VH`T6=U*8P!ndN)`z)#@- z?o-{~tZ23z^P87@wG;O;mHe6V^R`f^Rde6w0(C$|BmVhJDC}*Dh)qTn)EM1*Ar$aX z>B7~5YCrB+{k$d&7OZ~%C!6IbyZJ|aJ)4yko&wAde)r_(exY!lY~fbfvs)DwvK6+< zUfAmAAz>xDon5S(4Id7Bp1iqo=E$BcA8re12*1rgIdWzP?opx;=#$+FztEQ)+4E!< za%InvGq+W?JVM?gMT^-ME?%Odoku16k}hrCTqEj)RIXdElsd8j8qS6eh(9^3a-#Me zIfcSSDi+PoWp9tVSId50 z4z?QC*Y$7QFO*z<yrKKzHuX}|&3lhIPaF4Ba8KT}JNKv0sfTOs%&jhd zGD6#BSMGeyjTW}(XVmQu+%~yIkqH&AH)?3}`Q*uvf&HVGr_^rv{8;zn^{#2Yw7wR& z_CmuWuN%x$4|)AlXcFi(cWm&c4T%x$ZSpMe8#epUov+m+W1_#0I&*)9XURI3v@Zja zjx=4_woz1tuciL_5_P-j{R*EO-rINh;|jxq#LHoeJIz^8XnnPmp{kRo!^0Ebg`{2G z9r)?vu||gr6xz|H!|Uq>^6#ka((ursJi}iW{odMbb+P9oKfM{c%4wnP$+Ht{FCXaG z@yPh$&ZB$Q96l%_uj-n2-SIu2ocF(w@U~CqrMrd{yW$@^=Hj)cr>-`*!y7>v=zX zdPI5{oA~AIenr{dcv~^j{oVAEcHisOT)VfAWAC|tbT>V^QMZ>@<)$lMm8w4c$F-9! zK8#zs@OiH)b97w{K5N`J?;l>Tt@pM$MdvuT>6ER0=~6L`cK-My=)&Y4ZC5utX-sI= zdGqzPsfPx(+?(3iuH9+m)w4_m_s*~RyzY6(U-^&$mn)SHY zuslOz(M`${zk9TCuDef8 z)VZ(eoc3wu>N_e&kIw%3!IG0hHw~)mn6tMss?fnQr#mJ+_vzWw_N8HcT+VS;*~Z@tdWk=&{9$yr#rMXpE}pY@0b`+vH$A#f zTKTEJYG#P-kyTD5n|oaj4eOU^PAM3Au*~|)3*+}m=w}ISHss4g)U96)$Y<3+agb2bQW56Sa|Q4K3Df0wVd3? zjISK#F}l#n0op3r4%f1YJiH;k?I5B5iLv*W9=N%!x}o3tv?_Bo%VugG&P-nVFP$up ziVI1sylDPR506JnUdQB0vAVzF(zXRn-RF6~bdPE^^Us!^SA|5AXTKchT7(W<-uRIB z)qFd(Ydh5sh}4Ev-5l%HZCc^Z!wmi2+=|~i?|jvt!jrWN6t+W7*%q0fuj;V!olg$_ z>qW&edp7Os^4&eg{;soet3yMNcRRXu+2~q6rRwg%?Vu@19g8*jy39d0bmp1?GpSRyrjL2(nK=B`<*0X;qdq)) zR;k^1*VgKLg~r{iSh;BLO&?ZlZriBdmG4isr-s=t-S=eP`y+;ze>MGFZrBO+w^c=3 z6mNHU*2MY4b2_HXrVyo){LHh%QP(c`ZeyC_!n=vdr% zt;?1#8)oue&z3m-l4vVqf=ca=EhjOhE78dPO@Q ztMcuPd)l7sAD%ZHzHQpJ)!r`)Us!wLOIoEdD)rr2? z@>PeU(~fLX9#}rtLouO@W95^1yQ?O9F0>x&T+=1^k?COP9v`muD7)m(bM4kTH?*_e zVQ5h4k0C9$tV!EBIn3I-|BTU&pC?sx__1zy^s@mM!))&t>C|BSWxI;?+?#K48PVEd ztnDtFV~gwdeZ96wK*RQH{&0OZs$AZ}H5$(^@O9b9+s7uhu&W*4antx+B^*aP#VnsW zJgkIa>tMgmjb>a6SwBa6YFC%`MJB8-uDI@Y`1$7Y!`A+*>OiJD*3C$(qW8b?SIfV%e7U%$Gf;Ru2RL_KhSqfVi85PS~CWXxQR>up8kR7BicL*bTiDh%I=xskZbY~ zhi)@!#UOm^Um^+&uPIA26c0%0ijbH8=FP#fWy3jiUZT#4~vO>AnucGTm zUl>+xe*XnE?&mDJyU>|(hZaWkn0__fR9C;lx1&Q`%9LXMEk732jCkVWviCyK_amOH z>v^Z%lyx;y2llA8cJ*wKwmv`GFEvmZdYR#$F_C%~& zUG;viShRTtk(sx{K(>*~eXXI(yU-m${Mot>Utx*qbI4~paxV5j9!e6!Nx z(?|Ce+tst1OZbs`eU|34tMnz_rODo1hn~MnTTyz|(?T^uo_~)#uUPJXXZpc|RnAr} zJ<`2hn;3_7b_HVE&e}ilV71F54jmu=*P@-esnMH8?>f@y@!sX`C;Dvqv)`27Wj=_7+N2IrqIi_S=#cPxf9jUF`jGL{x8$Z=$mClD)06C0oBdIL>)O zZI^A;-e2r!`tai2_w}Le4(g|c{IUFs+kT&QF%{Zw2x*Y#d7^ESYp>!ZpB(Mj=TrXV zlwhYqYt(aV6f2@=>##G=(n)n+%ypd9<>UPA{a1gR@_FX=R#)~`a@=S?*?RD$^%ur_ zH+VI<%3Yh2lb=;OxoG_Aht)?;8X4Puh2qqTjGiz+9@7L|&Z9UqSuC@AE zZFSk`&yT+jF8?6MyIby0ip(DBxz+Vjwi08*XRZz{e#TYh;uaQDvfSsL+fJ=srP$Hr z#LV>*=ia@)w4>ijRm})TtDLJ%!~O1tM+_*o*)y`Lrf}SXS3ByLYT&i7lBxWS?F9{O zDo;B+>eQjSLz?98ULdtc&ef|r&Kh2`v-68V=Vz~7bESna<=TV0`BZm1ZmF-o6cBN4 za*L3=q1~sIJaTRE*q)};p402@_Py`zG-u?!vNJ+W`u5$=YD<0;Ts1`%)2*^scDTMo zuP%LJN{7RXy*_PSxxwMc>wMi)gHrQ%{Bf|_%W4rLip}e8C|veP)%Am)_jRihq4OQ{ zew%Bd=5L?+t?P5tvukMBrqVvS*51E&eT}YRw{~~-#7v5MwXRUGX3mTVpP5ce`;D1+ ztMtK9c^o}Ay;9aMu^~2e&b@oTG(U_Bt*KcDM- z8$16)2ff?=6lO2!w>M|gFPmI8{uIu{_wDuJWr<~F+5}X;()-WFO+Ak87&iaGwtX>k zBD9|qg9CEi^to8@gX6)@4n7Nt4YV%qSt4oW()Y%**TQP--T5%#!uI6)2L{e)FtAyZ z!r6kJ_+{&`&2#G`hw!`prLyloU_Vq9(Z>h9G#Iie>kqCo`O3?3Q#Lm+bT0GNYQUi# zR>cavcDh@4PLDacFP#q=(%-7xu(wq`jptH7g$`0K$nM?bQJy8ay<t!rRJ zzUm$3)@a*eb41_fm1;lSZe!eibwT_n`zdQx^N07ZI5a4z@qA%m$r*L6U$ouq@6qz} z`tP5QpKi9;$xue+JZ)8Yt^v!Io?drh=7%YfHLK}^60C<;ynSP^GDn||bM}{Rf4QllMZefyX^2zN$9D;r^-$#RndPF&Gw??cJo9O*0<^*6-$PIvyLFB*U8&VS-;E7BPhQAzWZQ!vho;(tFJ^bT>esGl?Ioit1ujZz)qQHpAJtoE zqS_CSditYy;M3=?p8tsYDU3~o>vS~Ivq{ZTpUZ6CzOrGNq$YQ~hxh99piF_cYb&oB z-MO~j>r=>#L5{j|{VTtjR8;rFMbW=O{fQ&W=iJ?*)U^+lpF20O9^GhWtu*JTVnbJz zKhQk&{Gn}oI_E4Ec63r;V7@Wy8}+Lea%uUX^VtS;YH6h^b(_tsy5(m1n^Ss)%^kRX z;H+xe=n_MY2On!W^IoN(AorFVzCQa9QU1Y^V#iz7*t_S&^oY17OPh!9S-JmSf@_b` z19wjTI4j52@x>}0GYnr?F(ziZUa@~hT3D;Am#=Pc3SOP9M8y|_dWD5v9zXqN-qk%y zTSe@cHF&B^6<3$9HBxqu9CSRUao=T+igkS#(Qe$1*CV$LQO!D$I_aZLsSU{ib+6CM z-|_h$yT*IiPab^f!^mnod#25PzIXe{A(z)b8xUS>ljHJsWpYd}HFb=k0U2?Mdjz<+bgnGmyM`eug2!MGPw(c1Z*-*{@U{Syk+%|^jVjzj&0va`@EBfo@F7eDlV#=EhTR!`XL{%Xk3avO&|Z2ffB=^btDKa{>Rca_4Y zcf|LdaWh}N_d2wGYU*jjxK;Jf{OI@O<*9LwKT7`S^`=IP;;)>C_&?8)_;~;GFVEjB z{wX|dc*uC=+)cL!75++5kLbMDwR>8&WyO99SGH~aDWol*b+6Ifd+VEcKlD4A{C4@u zFVFW?yf(pkdSZ;;|R}X5QbD^Y~NGRu`wf?0x_65a$wSh9+za@rrDBFiPXKvaj{(k>{Serhc_4 zap_CfKTf$G?dIB~MxS}5$2=P|s<1NRP05N8<;E>mzCO8XaM|K^6PkRs_VT`;f15+p zXqU}HZ#Jx6Lp}AP$BHfY7jEC&w?*%6@y${yAN#Y&(WNUsY#lT}`z?HO{ZGfAwCtR3 zSke9sRb4&bju=*I@A6i@U&}08b!lK)`RJQVF3#Q3>)`u7JxSdPiktMN zNy5T*8!ygV(y?UgacjENt98BE!2%biCflDoV4doE-Z^N?z6?_tY-nx$N`!SdVI*RKsS^AA0MrDW%^YIaz03ukgNp-Dj8*uhujDSi0lZ+fv6) zM4qWL(0!`I^*5c}s`hWv;ri>yKLdK4Twcg@VS3TtLh7iZtsD*weD*O-bMf_tQGeFV z8CK)k((8?_BLaE@P6(}P29Mkt zYjbIf!{^<>{Sp>F>|3*FHixx)!}m2Ez1L~QqZd*6aH8_c!Aq~# zxRtAP?9GfdMHWQQR^^x-A1;lE<(6IKXMjpPl`Vew{tA zeHq_spa1kNoVWSm=2iCA-+9QXNNTsO~!T%@WpS zo$mP#ypc4l$-vE9zXaKK%IR|D%#sI{=C>O&D^K2jgm&9#~@Fp_E?Lvz5VDvQExPD>ZF@)oNenFSrrADK+R> zwc;Up2hN{c^3c*1swVY!UtOe6Yac&6zNcU0+o<5~mwGFGa$IuhQcjszv(e1A2lqr2 zevy{H*uCm|r#>;U$p@ zQr=j%A7guBRr8<1h?|>|Htrngckt4Yb3GE5hPJuTq1Kr#t@rfOZXdt*Y1+~wDa&mi zuNk$WWUoJb!)&&CHkz_>e$8olw^cguBF%2l=6Y)zPx|A=)a4F0?ay}`6F4q5-n+)V z0;9`4_%w3toM{Dh?vGaKW^GKdF7$ZSxN#lBwtU|b8}`AzR@&Gl3mv@5yjW9Z_(Zp| zQzq#f+D@8bT3|b@lb6fbX*YUS(dPg2LXgk&>xl*SRBE3*<DW@d=^rRTZ*5tQebf zp>0q>?}9DAgV$x2syL-TCq2EJ`7ls+@QR}RG0m^CmvsC|Eae2{>}S?1EzJa zF#fe|E89jMeGfJLYg+3;H^P0kEZsajEN;%^5Bk)t;m*5qChHwWluzCBWuoh>s`rEU z#&6v5Cgn=ucCmqJ`BP7|pDGyBc3AtId2z7I#0hKmcXltn{O+5=Ift(CDr*zc=d9sz zw-pgqqXtf?JF9*8+O$ob_OCda&nKxuw-xzHnPxeuIVsZF;YUwC@u>9tRPy&d=H^V=>Z!`D|S@x0`WdC$w4 ztP6F$5Zj#q7c z15QVO`y-dFTm1P;mDMNx6bJ9wwspI8X#UIQfl-^gI&JIuSNjfu&mLR|(|yi+IqQJQ zr7}@H2?8=?RF}fdj{83`oDjW%fA1; z!q4y3@~OT1W#RKts;(ou?5S09LqwUq7jhOZ{JrkCmRVbr$ccHTV3j z%2thrCf)gKTFV*JuTAdxw94c1=Uo=8X|r<6v;yzfT$$x;P{urdvBd6fqDS+}P9Aw3 zlP7%e4f{SWaQ4An18oaU3O(@V?1X2bp-Y3~c8!_bBA@PJhqMo?gLAAe*TuT`n<>vs z7mu%~H+aOfjpe%MyWP87W&1X3&z^Ae()g`vo22gV>nb?c>a}J~m3$Wynl+r@dH-|G znYUYZ8(VOE!L*of1Kuv_Te&<=ZaJbLZzCigG5pVD>9L+7*pni{ z`}M_?es`Z&JGE)rPhs%;i4Ax889#P$3rh7J(P_=qkTx;T!}GfZmp`Go-!kOt(V7*U z>?-Che=X06%_)BNlUp@8_h-V90S%t7Q{--)wsO`0=Q}ntN-xuvC{)GMyOqu7YAHp^ zY|e9~aP4O;J~qy$_wsLkZfh5>zT-Mh^Dx=}p$rMDIP~l#k2a=C;a!T1&Re2Thbd!Q zmf4ikcj0U8>?1qkW{(}a?X>Aa-Wr#;uQ_mHw2O6FW!(KKF^SI_gs!>wbXqQ5{wXKB zzBn=XsAusb;mL3Ed_UsT<)pp-VC2Hqt6$#i*lC)#!Dh#y5sMGx^0Ysmuac(J7^C&B zgTqu$H#R(9Z{z1yo)ZgHjVacpyX)hTLvFNlQ2i9F6T|IWC>7o2PcGH)l)8+%N`bld zPyFlqJqi3@)SX3GoKcsp@!-MT-Q6v?77(N;Tncx0cXzko?p8R#-QANwL4pT@OVSMP zpeMKczr#B_)9?8Pd!M!5wazDZ^`GR)_i?o^CXR$LQ7x414p=C;aSUEjlX0_ggwwK; z$6leiu}0Z)`FQ1M$67>;O}59O3|_?rpSoSyUtAgCaTYB6d+er?u#<_Bhq7W8q%-2u zM-{Lza50s+3n-~WbF2~~WOvC{!Ix#0rS!T&s$TO3)upUu1HC7Z?Tdt;;bqcXHEeZzyCPU+}nIp0In!AE^;LbP9Nh!vBF^rhySM$_HHs!JM&{oIh3 z;7(Qdf}d~P$IY8?mhQTL58z_{{=p>~8{v@prI~i?kl) zNv$gupE8f7NS_AoqKToZVB#YtcY1#2wg5(WGz-I4&van9*TPDHxkUU?W`p5%Z-*^H z>kiguc#3kZ6LLQVllt3ay^|WEWnE)E0aFm}y7jV%TC4oy*)Rc-*ED6WXsxrzk!<>= zeUx8)DE@Ww{Yk6+$l6DoVFPR7d5QYNPf!0~s=f+{wLO|YT}?KSfd+f%b^9d!XV^!hn_~az3@nh1e-5A{@;QR zK-YwY!9)~(8->~=>o>TX_-)$z(#fdFe=y zY+Zu|7pl!9nPpU3pUpt?Gjgzqb5}M7K*4mItl1I$9=jb#=|Z53m*kweBT!*3%hacjvSlBrb*Sv2tJ)@7mlG?@Z`jv9r_VFTKEv=l2bM5@ zv$+`l1wjQ{6i>Or)6z-(&^d&HD`Pwy_UkWxuEhEGm7R%Ib(5JpR@v^GS3WK+eIpL6 zSY#v!7{ay;(0U6`YO$fRG`%kZ&7oz(8{;60(UNY(Y$dy; zQmw7z^o&wE>CLWvh5}D?dg@U4KR9MQ9yVxlYpyRosULYl1sygom5=K1%h_O7E-tPT z{wAFspka=78ZP$z)v^bD{r=RfA2im|7_#K|44*B^kVzuyV8*HTM-Mi)eaZwxUmhVr zGm+my8luW@Gb8lPkdf}ob_WMJ5-ty8m+yJn6Kow=jIXds_cW z)=xGHr1_PH+8BL;eTLM^fZJ+0U>l@zDeaSKzkPax8zO?%A@VWD5m;AM!qbWNrUjRQ zB?8A4Q;=#Uy*JEMnqIKZL$Go=#AD}eO*>78HH^|DvHI5wb;wi^AZQaty3{?C?(XP+WcMiaXt2mNBAu=DPw4t5 zyF~$TcPA9n%@nV4{v3E&qOdX|{L!3BgJ<{qs@eX(NKyY+xe7%4B{c#mi`MizUXKo& z_9jky7W-;x%16SnL@Nt?7%D4{3)Y~o!8FPS>{f&F`d+|nD-e0%=_^kT+ zx>F(MUKduHC+%F|c6OBpGDzg5)%9X`gze^2Hl)S?KHvsbDhg?JP2Z%Zy(A_PbZ&6M z$Eqk$2zp59j0Ji-y*Zb$9Px9P_BdDe$&TJ7t6CU{=3nyA@wSg%^rP-w< zd8L0a^yN(X2g8sA&o-S!lcS{~tEM|4Bjj+}eO2K((!yGDBY} zE)bKmZ(i;MCxoI!)^8|k0mT1P&Zw>gATJ)iQFln`*n`FniFGtge){;TYR+zg)R*yBc`dTUe9ODL!L-4A8ctrASk{@h z-MQ~}tvr~*S5M3Gx}hJ)mZLRkZU&piylur;E_-{o`YpgnM(jmbRUgq+ww&#-0)CuY zPKKyCg`H2hC1K($?>n9?ajqgPlo9je^dVTkJ2N#Q+NNy|6m*x*x8auEJ`o5>mCnm~ zxi_Hdh=@>9tlu3@GixwKmCifH&KZT9Nv2JOTdUE`FW<^y=RaF(v8J(w>1k_PN!!unh`30)4aXWF+7AN`q6D$>Izu7 z?;k*NW0)7~h?=JynxCQ@vTWVDIuupa=DR%BQjYvejS!3h$ssFO>%q0N|Fj@-*y*!H z41t@v3l1)&$uyp`O zJ@76%ql>7(OP$ezNNHpv+Ymc(4i={JqZb1hpN+7rb1xc|_pmLs z+s%%S7ze=%akkMGI|r(2kaolkrZXLFr}M2Jr+prQ7Dck_Z-=*)_Vj*HD1A1UN3Z#X z^RoOUmX)2ywH}VABSOr;yqn<9x=+E7DAAOUZs*56u5_1t$LqpX^|P-XvF!;kn%Oy3mZY~SiNUoV zj)ftOJ0df+)vgtzrpo^6q0iP+s1il{u@xfi7;W*&p}KQiOZ_WxOT=w+b&AI*&ymvP zct!^9;HSi-WIb{6{-7zZUsXNTHI?nRy9MDmc}Sd&(KRgivt%s`3RBYA@O}B@25-Y5 z-VC&t5z24d**3~C?U$qFxJFsTjOURh?0Eb?={xai#!<}COp$WxoBrqYIqMXc>kb|Kc)8lcWYJ@W zlqV0E`B58!zgJ~0P_Xm-Tf$wRjK6XA(eHwGz$hV0*~pi*7;|3$7uLj-&h8 zL9NS{w#PG|L`A>`h@qoR$x*?x=RL?vY^?2zDWo@OX3-OkkQ&-#nE@YT%8u0&UyPEG z&EC&SHQN($!9&MmJ8VS`CL2&s4N%96ilCu0c8N%RGVzHv%xbklA5g8P$DCo7Ue86Z z`De&#(|v_gm*k3{z5(<=@ZxqUJH~=rnKWjL@N!F%7T6*D5fGbS0_KaUnU8k91OM28lG^Mx@11GNH}S}>1vtnurA7f#F4TToA7Er!BIJLA^;^#U8B;3w zx-$|^8=X?s3%)XnqxF(bw|G~4j8dmN+z-x$IDM|{2tN1}=@a&KKj`C*Ug@^ut3%e~ zhRIc_tIGUP^!MHGpLO>|k=7OC)-nIVj04PwBoXjZrxMTs8O|2d5UrF~6&>@8^YmUG zUW^ME8I1n!q`+o9l+=q+$>K^d1Ec1cy^T&b7XUw7eKTae-{o_BG_3%lodJvoj_h9k z26y8|7%O2)Mp(97eLR1DO`GTHhTQTu)waZr9im)tL#;I`1i~EAEEG;moMMVb;EIUN z!v=>7mlT0O$IHzv5^lU^09F9T+k_*dN){Ib7-WaNayLUtWuyEOMn^~0dW%fg1OG?M z=D*F!b)tZn-*0oPvRWxAaDqr9Qy%;n0hn39LLow}zb`6V4v9YHz_(9I1W5!K$u?X}Q(`WSW4m zSWHsKQ5vu>7h|x)8w0IR(MbdHf&Sp%y85Xf=Rzn$-NG_iO{KJ`4j*)Ktiq@ zCsxX?4v)eI=?^Qml!uiB+~OMW^~Bpjl$ZZtq9j=UI{#Kb`b7QiBOT~w?~b>ZnvUH8 zaoZimDelx8UjVYVXMLj=P2k^s$?=-XJGqedcCdIWoAAzi1wu0_?epjvp1<Et%Q^ELaET8;+bS6259@%;AL>qRo+ z@2`)0uj|QBL&g;AYv}}fwhjaKqD<{cDNZE7wLy}yd4k$V-vz1spXESz_IHUsn1V4F zKe1gQHBg>OVgK~sDZ$ge=M;_&pE*5$HK(z+zZ(fjDC#p(xL zoC?23qfhIMQS~}vepkFb929uu(V9J3O^hszym46-qgQkst5$(ODS=rR0nvgxGE(=2 z!|dAF0yT0cV0fBeQEJ6z@-m7=3UV@|UACkob9-MTnXNd#H|K)%IukohsAU9xN`>_0j$R~1N_`%6YF&$6998VL04GMgGhchRSngf!&o8Tuv=3OToojp zokfKln(os+OV$}L#}6VOWXU%!h<~l&`i;*KdVhkY*eXHLh6t$0i}P@Pg?0rDh)$6r z_#z&~2vD4J>}&3jc`Z+6h_oy3x;VqiXko;U99+Y)kvSSVYVd9` zM5Grk_0$!37BM)d zS%B~hz4;Beq(2BsM-E+}X=do+tq-8&WwNb7Y$x~|E-UAJbwS{#t|?;%?yfc-BQ#;f zYPJxQppGXQnEj(zfr{h~{)Vu>U^XWE?!YjmigkqiL#$&9vUS8S8E#roZIh{fTT+HI z-~N9vMDdUw3#SvfpiA{z{PM5$V9^ivv7ik(vJ=``A1TI@cVJ{)fa2=Vnv#*eU+TAy z1UB~9e=sEe^(H^Cxk-iVqgIn0NWBFE+%~JwhIA6f2mjRSxXHl`XT8D~?Vdk>9AVx4Sp7m+>Rv8UZFvy7d* zVZvgnk!l)0|8Z;%?Fpf>el;D770xX(7G;Cv5EmYc_{~}?sQup1H-6&}Paqru08_k8 z#JBO=XE!W7$^C}AP-=hHO|6iWsL|H5Mip$>sj8_;r>O9Xa(>AzT=KO#|Gm}bg$}fp z)35t0Ua^Uv*xHZ}5K*jGO`QVs5IryL*u-6j>o~(1@Kc|+7`GW)vk#1Jbjv2mk<#a(C)H<-&+Ln``48UIB!9i>J5{BZ&fsL^0tk~a0z4&N9us{6PSr&~HE zyV-5)MaFw$0^W-|mR#B$!{6*6b&`Zk?RH$FT5>BZuLc?hsO(T>@~q|3lLHO3))GC9 z*E8u;fHzk+*(96OBz-;1Gl*r^&;66w0oHJHJ?llW)TRerd2FKyw=#gOB587i{CRR5 zLiNF4biIaM+=5grmIUW96uCdmM!IbjPdsvaX#jXY-wovRyIDUc9RpA9T}v%IM2#4# z+7gRF<+0?@y;*z}BeY8%#W;i?R&J{L_V7rxb|1QCAPp(fnm-e2KCkOu&?^BwIiVud zmoW&VO;Fr|OhurmKrgl>#C)+M|G$m({}J2ZH%#)A$0E^93=h#f(QVN(RbJNZ)Qpo9 zGa=y5P0@x4&FO7#cz%10Wp?Puhb1Km!{{7MXs`2P_tM+{2V*^VsBv^O8$w_`?vfElje-L|{^K7TwcrL$==H?Itk*DS&Q+>{*`k{8nIxVkqDIlc(&9D!Xo}J8RZ}G_h z|8B4MZXls9V|6_4WFYSv7k6EpKh@#Vxoa|IegzkDEh_uQV7?3v^fcjo3A_KmvyE9x z2$L6SMI+2jb31e{3$B^Ne&^2Zh8WY=Gks<})-C8;V=KSJ*S!8}^!{cTDD+V6qlWf) zMW2-Y6nWO+tQwAu7h0ekfiG4G*AN>Eb;n&7alCk*uPd7JWmoy!NAGvpv`w6ACb_^& zn^@-6D6k0*{AB#Kf-88daFN~uB3NKAukt= zUGsrAd-43Ito^nj~3ty1ivZ3`z0N_$-F^lZX;3O-n@bAoC=;! z?o)Bh=tU{J`(>rj*$%LeLYI7Jgep~N&ou=y<&ao z2PQp(MGy7P#|dY#6RWcX_T&nq0;haY5+LRrqR9BKsjZALzcEU$*`B|CIm7Zk`3#_l zC)z=@6um==)dy075g3PQW`Le%x!EypA1Jpm`g~ukSb!A`G@wv}@SKy>jwDkqe88}U zRYLDv3+B0PHWgrnt0-s3^3s{=8c1ZI6QsjxG@P$ARe>#oJwd#=PUp}6LBJvS{5L~; zzAM$}-pHxnR6uuP{5}G#SSSBov=7XnMV8m{k|M5)eQMq{ODH{{kq)2G$&KtWKkYG_ zAj@3TlFnm>4a?h?GVvt;`VU6)w)zv@GBn%ul{yzd^`}emHj=fvtGg{tn0U*o#c?xn zbWROpT-;?2f7S2jm4tIC8wm%*YhmZv9pp~0La~Z*k80l?jkJ=3Pt7FLXwZI>yKBEv zp+7f+gXI`OU0A{2N1#=^)aKpAuaGXQ5OamiZm-*OR~IoqvfpVtS!0q5cXXxA9dDTa z;Y{GP(Y#)>7O!1|B(?6L|G^@WWqrB>Hl)aa1L_&RRS@Vl+UP~URi3uRkhFnu=;7A6 z{x7H1T=`1 zO;{>hY%-;OM$1q$aZNu*p@+w$ier#-VETo~jimL7Zr4A6mpdD_r|tv1XPN)pQMKaz z&yo%^pu(a;qSUk%o6xT_eZ>q5C&#w-pJf$mW;q!XYf_`}Id{f9PRA?;Mw|G)Tpg|v zo`&wByQLuBG(fi^!$@QdJvX|1` zF+6aorpegp&`NjM&~KV_MP9#O*&PJkX7ANmWLJ@xRC=&G%AYAp%?$7bC~2H1#lAZn zE&0jd#z+(NDYNfi7_rvb;(It$dKx%-%&W8rZ8SE@ONeLP`@oAw1k-c0nZ#r*o6z*z ze^gr%U)^w*Nnwr6))G2HSk`} ztL=>_TXK6M?wa+S4bKLiv3RplNMiM3(>RHlb8sxmBJj4#2)(3nTWQR+O_UK8OBn6M z{j{bq^Hd&ByuWA6b}C_U!0nXSgb?alO^vy^Dwq1ZSmTgn#)-zKvnrP4iheD%aSGnt zgp6PyCv{)-aEWi#_ggsJqUUl8lIY=Zlpfo^nBA?25(%Y}jYh4C~=k8Lypbu#T^|)--Y2g@jnl zQUYb(eysAm#n$d z+Rw!F`NODS5ps?4>H#Ub!3F*p6n0tjYa8kV6_)1>BoabFN{ko{AQW|K7eX32t)s;n zKdf&al0=E4Fe;Wt`={zLGGYAG{A91cOtVQP=AP<4$NR)eAxwoxW z#L#T>bDpho&z===i43=L0o;MZ+ z)iI5o`d19N7X}xc>lqp)sJ7OgAaSPNZ+EAu3=-L8m84^%Yv;|%9th;(B&FkG1J&;Q zo9AcW#(1Q{Mcv_J!a})YbBU>_Oh+$x+TeG1dO99II=D%mD$F@&%FDwMO1>9a>Fe}!B0?hT5V?8h%Xm3o`Cv*+RPwuWPiFqrc;UZd1`TumZn1vo zNT>|*80gHA1|X(vE%OyzoXMQIsMq9gErMIo07fmBq0o-T$TtLK1chY~KzGhU)O~}@ zie$re#nGp|RDa!->}MXdJ>BYnNEk)FiR2>k^Zayal%PhF{b-|)OrDeib8_B72WmLK zH_w2K&nSzEq(eP0Pu5j5^JSr0i!0R>CpD#=nB-~l3>Nz8wOVaA|;;FgUY zk4%KOvk6Ss_O_Ju3MSb&R%v1zu1Gb#@jS0em0=2=06vr0hG zoZK)2hiO)y9dJdF)s~b@ML-$Olx`W*&7Mcs9<}xKyB9ipgEoa1>ChN-XIXa{kT$>G zZ!8bZwud|)rkO$xe*AH3VDb1XZbRc|d%l`>y;YuCugB`sv-+h*9hL7zk7ocd#)3YF zs_wB9SL^>*lnyq?Vf%=Q)WH4br^fAhB28v$fXpKI8hz$s7HKJkSu83oOTldZP2RVB zuy^RGo#s^|zA9#*aQf#h5VrC~jn#Irdc?LlaAn0Pq0TdHX51p`5vu7%C9N~#P4gAH zh0c`4(mLL2uZ4fzdir2MKvAMmd32ZG9OLOAMg(FjRA8@^qyri*!>5yc=(%ND47kAYCvdqVFdoLsBJW4GpTV*>on@? zHxVM*jBIOr-Lii3{kb>_r64Iw{n8#FJ z;!!1lnx>hrKHO6x>ztM_N2zvXc=xuTCX;_KYn042<}^SoWuVasZdoppY2w$wLT-uiew1VVJr)xwS}%Nh@8 zX=4p<@T{3^y!#xt4i^c9dANWZ`)Qw=2fEs8WHb{p4B4kOz0R(_5xU#(dohgkV#Nrd zHdRR#biH&m&l}g=%KODZ(sdxhH&JuBj+da3SwXn^(Yh`K?jWBHTt(eoDoh3AM$;w2 zUS0d7=@YxSZ(*!kt7OA{w3=V2(E~7|uAF~}&nVM=C1gGjItlOe{&)?0-1Ux*(b7YO z4Qwn>x}vH#XI5c0b8nJzjqL1mS$dv1?$U2q^s?esj4S2a9vOWY0u23_8&@iQM%>8R zsEnGuTt}31QtvSmLRctcU)=IBLqwwlNU49JPW~)R7-cE7UnnuTwk#x8{=-kIGKr?A zy*x+uPV6!ffzo(~3GgKOQib|fV4o~;Q|0n=@H^3bZ-atw?xYfp;&WqzeLCGhnbXE? z1WbGtD>}=z+xWuDk)@~kX%o%ag#TdZ@-)X*JL0`aCfWIsGC$WbBV!}2ScschqR}Bv zR}NuaY|_%nvWx{`REMrPorow@J@pF8`M`eucuW1@vkIvYx`6$G+2=N2U}L)`E@g$( zgyFkRCg-x;(~=i|iXo62-->ECnG=gl{^i(A_osi4nd(7e4ROM!*!i<6>3=YB`)wXk zxKloPo2Om`Mq5VSjm-ya2K5~Vj^Cf|@$h2TYgyKkoc78;w;T;3oei0Y?i6F-!dvFu zZIkCI1^zYkX6&kP2`pA)5`v5AQq zFJVgIMCq0}4XJ$}?=BuOBqfqs(*&<{fT`Dm#pNHT)c%a;DR+%#3@NtT&w{i^@!-4- z@jgHts)#^dd*ZVhcfy`rjRwRk-w%QMZl12L+%7{lcflXX*d*)+#@=(er7Lo-*LnTE zh!GW7(RzjuH60Zrt~3ALb;G`}r=RC6tQL)_62k~D(~bAUsTBfrI6B(cv|~T@YYJvZ zH!!*B$?>Jr>(?51bXy=N^_ELjhV!a!zY~X?C^V5+%_X~J5Td)cjY{s+%Kt;~s8K<3YZ}8+-7ukm3;;T^3#L7XzdZZ1wI+jV&z~mya7^Ns$4UV zXz3qF$=ID6jX&UIC5bux3TTLXzTA8MCJ&spGne!Drs@+Ldq$Br3Go)(wNSLSjotAn zEDcKMKH-+=Y07>Z@`ulL`~XA?QI&4PCd*0nGrgzb);^A@nA77oO`keb?z8N%=fT;M zT~U`?{p$e|y=s&w@Lv^UM11v5n^1WjzT57s9EypPoTryY{h|e{Gdg-B9D7DCaQ|iv zT!8jvRa6_}^m~IY&}W;Atus=`mwG{@4%`w&O(x4ZpU&rh;k2@LrJu%SMK&>9i5Qm) zWZOLI>$~9+^w$dNSMK#{Bo(pcSc_-l+65*sqn>GJC^)XGAeTe7{Q|!s{)0(|KX_;* z+P&B7zFYKXWeOcccVSADHoRsfh7%%UFQC{e^0_UvW4cj?cF$}y*pmaet1L}d!r-X& z$WQ>TU0R6Pyq!B7Uk@enHl&w-NMgI;hPS$YFK!{SrQvD4*{WU|at-}u756p!3pG`a z+dKmS33D82{n1KhniN9&PT>89p|!-5(^%de{(k$QrZ4ghPbm3pF_K_z%x+AvytqXr z&HHhqWxdYoY`lTLWj)CY3pS0WXi*kyW&I-G`d#5zFnQ7uPS@AJDj%`?l0$PYoa79J zqonRVQ!l^bxk|`6^&V(J(mb>I9gUODV}x}Pec1WMqs?=iU}Cv(UQo3#ktNzHtkB%U z;(Qw14^Hm2G71(4n9+)=?i=lDSRg<_AD()d>>Af0=5t!-8aJ_@E*B|&sOB<3j3}$cu8Dj)4rv-Ph{IZo zi#}v2VwV`6;3rDAMGbx+-p}#aY9k9%We4iVaIZ0LbZIYrM z`Hp+n3a!M1X)1KwASXh^+ETK&8SQE%k8 zHf(KnWzY`QZki2sd#EKEYg7s+-!%FMGnJ`Y0$R-?Uol2XH_YfxyfS73nu5ZXpr$`| zlAIb_dT1;~7%Nbrg#&JKXi}mRie?r^Et#)`UiVVubN~Pp?iOQhUQx%XNLw^m3M+tV z1SXWM`?MFj5_(}OLUcph=-U^pmTpOymmmvyt)xjpRkFZ~vUu)`54H2BjqSy=3i7R& ztp|V?c6qWuI=#Uxj+FwvZLzHdTi;m~cP5diB0zi1&=HF2=A0Pl^s#3>vcQK}WpdKX zvd|d9x=aF#eDPW(dx8;*!MHg|2vIKJ8V;YIBZoOQQW%gEYC8KC2z!Gzn<31S*;ZE@ zQ`qw(@gxQ}PipMMBzYV7sM-eJ_~FbBHyBAVO&}c?Bc-cqjjwlz)Ii2Jt-H1Io+BG? zzdc{+utPE|9;@aguM>*`er7tnG&0*{|4x7fltTjW563Rb@zSD+s_?U~)qLaUg?4j! z0%<;j7>qVUnpV7KQ#zeCTP@Otc3e5c&oH3}xf&_vx&uQ;-Bddgu7h)S`Xj}5*5Lxg zw9-UB7|jP)=4Q0x*bD4{T+7_@3HUApX_%>wg^^utOx5`RY1Fo64%(mWS zYo}G$!ZY5T^A=L4^oQt<0+n5H@ujcwSG7-m67%Hc-)<9;r;j+j`g{r%FMl+V>WzKe zk>X}@oAf{dv!hlPb`obe()Kv!u?{2{(j5v7E87nEBaE=~#Jz23W(mh9RibFI)iiJ= zyEHgfxH|B}U|FhAX(2=njtVk+;-{D)FZyy2Oyxwj8lYxMlD(+uVFDVFtkg&vMISx{ zqveRa6!jt-b~T2zBB*V{Y+B=|mb*NKD9H}iFiCkletAyiLt|i6!>G|Tf69&=>A-e* z#^13vu@z&zwcmrkX})z|t0az_)RtKtdib#4n9q|dv@7}x4UH5Hhhv4&@t97rRqr2+ zZBBP++xfJHM?>A0NK)(wN|enX7WSsFSjjX79~=iu*(Q2U{#URNtE&e_v!j##v_u+Pl&$M<=>y@ z%G2h(B2ArCgmo@{A9nUwF$R4t&Q{$2^tH09Q3=pCfXU1tB^&*YGh%a#<=}pW1f^s5 zso$?Nk+K2r+S z3+sN4UyTC9(U?6GN&16zKYMxh&8A3_XIa^|K3Cf!GY+Q{xZQBK^^kcKiDNsJLD6+< zSF8-C_;yg(BkxpIvFE)2zRMXf`lcU{c&w1Eyu%_Lx$g}>{oocIT&P@uJlAy*_%AE! z;bEaW<6^JVJ;c6*embJ8w~N&U7Z!OIttCRcS-yWHPCor>4`HyLWjFRojl@N7;KWXE z&BiP%^&6hfG?EXW#oyzjI?$M&rj59DEO5xGaWqN4o__RNZQRV)3@6&MB%O^&@VrQ_ ze^UuQljtdX)boN895GS>0I-o$y^>PY%3^QLWrA=rv+AK58Z9` zcXtD)JYX}L9yS7Ft{F>~3<>;FJm( zlARnXiR7xYJHk12@B@SOaEY70rM}!Vyl|aFoH`M433M!eEsm9pc~(A&C$5in@;giz z(Z3XNY$C`|(VwR+_+yxr=CCXCftqRU(5ShVcuV{9_$mK|Pv!!$yCTyO_aD9clFwF+ z$Dm1PqDUnhjLf(;#Uw_zufBJvRyb^Mnmh#Iv?jvj4xjsthgqd2;Tig=>*;0;)ie*d z&EVnk{ZU)(lFqA>77q1atxU8}P5Fps-#CB^4i`b>z33t|x-qi~H8ejT8{5m^^utEh zvG2M~rDpllt_lyA*Ik#Oa3jAhaU5C*>Dy$pQg%K`5C-Iak@BTUX~Zh+U|Bx@TX8=v*R7mBP zC|%~e0@Z^jEJ8Tv@(nBC?VW-QPbCUd%Qag$WBiar%3FJIMm%I@xv6C>wQ|#gv<&_@ zsQngKRW`aCt|?il;;|!TIbb&GVB1kY`JE4V|3UUGnNF>GKC>y`$l}ywk(IZcprF@$ z>PVb19o-E_JMe&jk?|RLWR-<)cc9G+8?zxg9Q7!@`lx*}a>TgSY#0}n3C`h2R7bYT zv&LhI3+c~s%yGmaM|Mfuq|76Iox=~cz^WeJ)JbdQIc3uYyr07}NImI4UpPd$GI2xO z&>Wl~)d%3I@eD~P;?elA-Im-Xf*wInODKVZuc||XVdG32REUJ7-$IbbSToU}R-ons zw*V{D!GhAP-ZDd^2$=}D<&ahkG73<)xK2fXl#und=g_IGjRQ#>#kJxOYlj!RF;(EN z;GcsOZ&Xn%*zxY?ACI3twEz0d5zJUvjZchp)H3fytjO9gN{|GH#SUl53tMp@r=>;q z%J8kitD7qCqvfO0?ODtBz%l}6qUzs4DU!QORH=tqzz&y3Y$h%!!B3Y{DA)K7)V70WyLVv}Q$A zIQy9-*P9tnqUUZMS;$AWr$9Lhf(dySG$mgLRTj{^kgI@@&YzCGAM69lWc@Z}suV{t zZGca$y5!JV5oV*zFSFE>OW;vhl>%t^6n3 zA;Ko(5LHNhJ&#A280(+Cm&}k_2M5)M}yvUI0ba8Udo`g zm`lMa9j+#xrc;zGa_73pbQ|)?n$V_#;gq(FMWPM{!%m@Z`---Lb2~j=l4kw=0Vp^2 zJh?0Sxj&>T=WC#8%d#lqB|%cB9!HDs6!pd;g`)2(?#*L9<2a4HhQhSF@6SfT9XCFx zz1KJxrlFx=5`o|_*KV|po)DXkHIq{4Hr@GMVkLm6t+Xg2q!m~CVt`X9(pfi1gI+BS z%R6H+E{yrm*_WlqIzZOiV_sj)T~L!G9qm9VVMc)d{>Mihmm%Rv=}V(MLAYd7t73*j zy6xVrKa8nUrRA_$_{`(`l<8`72KE7@dhqC0?wsiw%GP;~>}#zTMma9*war{guGL>S zPqaD=$nigG8J&t5C_pM^`7^ldC)9brU?^3iOOUQxj=`PI%Fi3Hs^WJ}1Z*OHmPZxg z)r7s`UVByWl^UEVq}WnI-!SaroC7Kxhe-x%dvdG;lazaqJkh6FSofZfAP4e_2zy! z+tNkZ8C|J`WfKgW?+EFn-8GF>mR|7u6@&bJ<(O3uaN*)h(+D|njpyla)!*PyNbh%s zKW%O%tIyN4C})9oVmjVxeZu^LNMUZ05ho-#D?h2An$DNDRP@dhh&4STYi!t3d?eLe z9KPXW0+rDq?&?)WT4*;}5z~|sZ0q;VH?X8uTW+C&kVLoJdWUjf9_(cQ^1OfFpQ0WP z@C39v0xYeKL7X9gi4iXpMK3#`3ZXb@{NJh`{tsaA{|ikIn)&;^KXeunUK=^cP@)%; z1W@ef^2a8sb(hsVuFq>$g5Fga^X&2GqBxY=R+XLxi?9|xY*4C+pHkq4{S}=uulQ@` zcVVz%Ix0tHjZ=cC&Kyz)2K$nY-X-Px2esAyyfIeMT;)VD?yb9zveNy`JFR$Vvsaf0 zAu3YeXgUE<-dlU1=;7}w-N~s)Z=`z{a%z&QvGP0g2k#&LZ}qlWe$tU-MPp%xh_(*FR^tgM(#!# z+7kNxSvP?%l~~W$Vb$h)*WfL$oXN}rRtiAa8W#-%ZwzDI?PPk2Doo#T;Kja?wMXMI}`_X>$4A|y*sFSyOrXY$8Gli}Gi-wz* z_pMCNh4v5W1XLiDO{{-qE^POKklAV|(K90Z^Lv=-N11KUDOxu4J%1I>?Ah)k6RVWV z5#u#-y|W;q*K>$wegd*4t(+gvlxdSvYw6+fvg9^yQP^wa`1+-iEAK2Gs<)9(f&TWKMSUE+vSE1z<3I6#x+z4Yo0yl7o{wZdJK z4SD4}DY{=4@_)r6#WxhT-Ty6E+nv&!=ztFl%eyoiYClF)RK_~Xx)7`MCb>P)X>%Km zAT>j_wpDdT%s6d#*t^8gfG%Mlh>oi0uXFU<{orkWXxMgR0Ub+r`>&ycH|U10w7OZ0 ze$XSYwhoa<4~9u@BWU6vrf^@3+oxrvHASl_dHcMPeT<#s3k~ko`w(nd`rP7r%Usml zwBl|T+2c)|?1N_j{09>zLvDTS_IXTqXMHq%2`=X)a$jvkeDO#tsVAX=WDC`u-gr;3 zwJ~3bMj_jab|Yl`HU2(nrSG;-yZ0N^Ki^g*Ksnmpa%CN3`0gnW!Y}h7SSy9#NQa7A zj>71Xml1`VEnFUxKrbhsfVr1CNEj=sO?9tPkAjyPdWR=4tBC zHQey=ipy;V8UWvITG>sFzk7%kn+;~tRPE(O69s5feRR!ki1(+jIpGa zBp34UI(<2ZJQzki1wQW;d_MKeuP*IpytGIbd26%8rmN_oIK(ItW;5;1JFmT@3;5X@ z`riER3;g)C(`a10Z`fv_J6fL`y~&5GKgM$^IPYn;)K~f6HyC>p{HflMx(SgNgW5b% z<`b_i>Hdfcg3~Rzc8)Qf>Ib8qdChZ%xgZxLTRV~}SVa`CO&l<Wi(R<)W)~_F*BV&yjNp0Eu4OaP8QIO`C90GLp;4cwrDQ}@+!s#<{InGv(j95 z^@3A$oOr$ND6;NV^HCjb>|BM=%g{MLJ{%qteo`|FKWCW}K&SX5lY#z;WVbyfl4QEe z3;FA-W?71uJJ3FvGs$8sKg?k4b7-tR!7(%ANP?Cb5Nx_<1|-R$RH!`|ss&qlMJ2!k zXA)+!eT}Lu$kcj;=1&iVdybV4qRyRkva5f@RLIg_2+c>-P;PL`HOqYKR70C0ZRgOo zjK$-s`Uj)sH3ib|cBXuXb}IAA{{DmU=;W4ebuxb8XJgVWvu-A7ZS9dBOLbsCbe*cE zqE+q@Z1^zy1C2v~#j`dIY>T%H6A!l= z_*2YT-a}(_lT0Z;AiL5GjOlRR_Y2El!Pvifi%InLA5VK`zfg>X6p*H82-`i=a8(X^ z+GYiHBI@ddU?-!VqwtjZE-w@AMAp{jq6qsEE9_i6eI(Qvu5~QvAXuY;ef961e+?9w zT~JGX{+ox5MzH~tQa{Z=1vzSG`_M$pbVvNWpxSxX6kTG;(NYF#Izz>r@61g@hHssn z^D+TqP$N8Qg6ECp1-xaF(tnn+uLgw1jDmb;=F=QryO?O-&H-LT!YSsD_0(VY1uMBJ0< zK!NAra(jhdifpz4n;NVX+0Y^q>7o^Z=H|CA_36s*dO>QJR3q|Wc&?BQPp&TP3ZWFq z1S`uvgPBd>uFZ?$2|8qi|8+}#+qb~Uk<}nSxtk+|C-d*~Rl}YE6)9^A2pZ5+wNuyt zQU_k`VO%hzRRl$b*==|eJ9YA3Ow<43B4WxV;^V5scQh9dF6 z%ZReX5$(zMH{o>uz_djqtCX;pcrUS8+ns*GIK--9hiz@qvBe&}1YJp#0EXp4l;x!t zE$n~NHpCIuZOYjQ!&q#T^GD>`$4(o{vr(C9Ih*OIYV2iVZ@t=^B+Q%^0+7Oqiz=qO zFAAGRI?bYGRj`R;?&u8v!QiiFn5ul%^&6JxWJ4B?YBl=P=chj}A{L?>gkGweMFWM{ zq%D(L{~W$b=bhxF)5LG>ep$b_AC)xYy4O*3lTIZILs+lh~!n{KaJdAuu*J*jHb zRGF|!lW(zTI5^Yvs}N&axv-di;>D}x0PY2}O4 zk-PpVIiZ~elGb&K@r|NmN~m?`ah|pha*W;oP*bBa&;{fZzCBizu{4xpg;eC*zDeNP zCW6#ey?7edRXB;$NDot$CPPsS*mvXpy+8THRjOM%Lvqmo0FBSo?K$ZBMat)AuR9G> zuQmTRGi>!FgXCg$*{=bFq|M}DR12!?CNnNOIPw@^_5+rbXeGo%E8EN2f_&kNj?ZL` zr;m`xtoA1%>;~`59%^ePS`U6Cs@0CU5+VRuX!yg zjB;MbNsE>Tck{OBPcd`GZk2#SuiECb$p$5hq!G)U;Iw?U7RC<&>)U_usk6?AjqrrO z5P%hdnaVKBwWpeHi~_6)EbXWvu9qEl?bNKw?|!9r=Hrb!uE}P{favpYsMwdNQ0M92 zYpiJA?U&S|N-C)Hj@Fx6gC6mY119qm)btj3xG(-FX_nPT+YznP-0JRigRLKFU1sZlhuc211HRmx z&Zg{$)Z0QV5*P*;m{dJ4UeY)Y@pUzMjl*y?KM!wB7hZ6%oRU&4pEQ;J7kh6JRL38N zYvS(i!QI{6Ik+C2gS$Hc8u%UUXOW z=GV{ne$VSvl+zH>9gvuDUd@u)Pc8KiN&&-OM|UmAl*P{>apm-lKQ4LxX^lXPuI{KV zJx)QRv4GDIQ!babwG%Jq{cgnSq`N8eUafIE#A`42Y7(f^O$Nhjlb@HJ{8Vz@Vz=Ru zuevT!IYNoA8dHNcu{X3@YS}4EU7`ZbZ!OjrGu@GZ+ekg7?wn*R*i>lY&R2-#L&!=X zN3d$;{pll^o8iaGME-BzrSGHjgcZIzp+-=wITE3Dycbp%sUEiF_n2Wt z#QE~dBL(&yn;ENGi;UVeS?UhXp+weAZnw3PgeL(aWD8%U+5*ufBPxSV8P-FtOr3rF zH{8^1mTm7ixTl+|Fm6urh-lU7vTZ{6{1Sugyz5|rV^5GtAcN_&@eFQ??aY_=z+VZk zmVRgwStXI@Z<&M5Y*q<;OrrE+#JP}uG26~%KOD7kLr4fA4>1LsX4!lym@CH6fqW&( zL4gz4A15;0{QO9)>nL+b5oceDiE-eHo{GNj0qpM{6 zgCg9dR07~zKv=GXAOz}g^jtjnBImo!BpD@t3Dbt^HPZt-cqC}th6-WPQsx?>Z1VaR zoX?N4ajpyTdH2osd9l7yYK;-@%S-orG~FEVW5LpKTc=*z#|NMH;EOX@+nhQ!R!xqt z4e7<+C6($$T9`9y%{W$j%=OhZpqDTz3ksmCp!MG-dzy;`z|QFW+9T8zgP}AC z_MO@JgJ~|XX`$dSMu+ZVwys+vx*-%ujMbj%ObOVbeN)w(R_a?a(bBZKtJzuoO>^g0 zBNmv>={K$L;k9f@KzYQFx!g$uJavQ?d?O!ZaF3~IdT)@wFM-$h;Aq8eU->18m9eX>!+0Y@;X>Px%4kt3 zEqCHK=-BAYF!EAw?p_5y;pW)G{Dbmo!T38P_Xs*X)0VI>t2kLh^}6Aq_{rG*5$%AB z5?+`+DvoXLsE=VNf#>>-+M6F0SUg=x?oF)B*MfJV+}E9AZNi@_o5X&l&JH z>3=RMz%j+cPtWc%8g#Bz8}fpX{X=@{g5_(h|qPnZ+@IL`Hbi>r0OBf z(lt(n%RZ`6mg{3f-~+Cbq&Va-B6w2KUbYUS4l9ts>Fb~Y4I-7svAk%Vo@9pVB5NcN zd)>-@HFa2A`Dj~^qqx6$%2jGlf9NRzEL}N6mNG=~$i4AV3I5XAE_4<;lm8;Zj%u}qe+LIp9_;dMID!eRPi zn9ydp{kXdZAiRx}!Nr{(&CNsfCUJRvoshvR9`SJV0o zdQjm}?F6^+KO;D$eon6+IP@ZGQa(o~N{*2VKV5}xnM5?pX%?YnA4riO&m_C8;o?aC z8ijbUW^Wp_ONw!5^}jSGvy0*N)V)HT7S*6UKb2NRxKjU7cMj-P6GGW-)$(OdE{+N3 zUtv-}8cn33;=f*@pCwY59p}g*J-ao&3{{h1-h;3j{1u`3Sr>{YRo=qur-Jwo3P5rd z##{rWR&Y(F6mmOZ1T&LStNII9f|@ZqNg%(Ej;+t;vVb?)W>gX7@u{J}yLXhp?vzPu z8{oo@($maN4WNR*km&H9q+<3T6lJB^ZGuxwg^vY(CaM%lfjX22WuO|`b zmpFM)T_|Y9(>U11I?6Z%Gwj4I<)$iP*3W@4GYf4&@wsA)K=mng;@R#yN2=#KBZT9B zP;rSUTeDQ37kOHL)LPM3<+=FeYlV)^mfO0` zgq-|**xj23+6)W(mdaw&-CK)$$u^S|LDkjX6A@I^YP5_#4iR5HcWiI1GTBz>@N*yz z4&3!NER(Rg2o=r(P;C2nHH{Em`!!2Wl`s4r`!35993utZ5Mc+&B^&g9AT zfFaq@Yc8&atfj}S|NRQ&e|+RWKJp(Q`HzqM$4CB8^O0;PcB|{5&#|eHYRP{6R#~98 zhGR^=01xCvoP1qw7ZMY4vUM|a>>^J7>xyh6})qC`x@YPPq7{1mOjx~&k z0#xh9VWf|}XtdOlrZm0vt?DvBZKC8Ks)~IWX8aG>4;nAe+;XCqi$}6u7!EN4nv@Lp z`PVodV$4_;@NazR(Sk(e4QUrGOrX$$>5x)J$ctw~R#lXUPFzi^Qsemx8E5BRCtH3? z_qL*XPUUAou^^f>zQok3LY(lu?;H3KN<1i6g$h%=2$-hJfnPs+Cy^B;Q4E2&9*bqZ ze2VLmMunhD!&vr6JuW^7+Oy@=<~wSQG0FB|`6%J)O~lB#379_kvj^aGI?B)QPHp+3 zW>lm4)&-{AUegKkZ zbJ72OF06x}j$jfFq^ z)phzR#^DW6jh?&>7L%eiCp_2ZuD<*7NRCpS}$rA|tn8hGuP+SWrKqU6zN znql~ZJW@Y0GT>6NN-sM(SuuismGz^)~iI4Y^7W zM3aWY0iYO_XU#C)%!|@lh*N^W|wUIVr%&|Y~E}V}&4St+hNecKH@qHli-r)QT z*tAFQ*CrRXBJpUIl=iea^Cq}J;p2%F``_v=y56%=S0Sjw`VALTr0LE>gqk;2kyQHnLf#o7R(5UcVk*xV+leh!edvd6wp~xD!{_G zhVSs)Ql!<(Q7FA<2?adXTUJN$Ue%GfNy@U&gfb-xpqQ7?`@C6iyxXoAo*5c5!mvxb z`KXEF5zwI1%IldL@sS9!bBduY>EAz$(&AzOM~6q`xMaNZx;e5H$AGk=Kgx8$*{MIVkg_q`sp}1wWUy&8g$<99FUMJkvaUJvFSVq??5CQB0wx>dd}&vx4`-C@Ts66fEiO`IvP4zz4k zO30hueIDjBT{?$1Uv;;}&s&?zHLe!5>s;dVvjO^bn!lZ98c(a^X>DU#to_teMWMRj z3%IV;-J6{_5oSx$$1<4ZDJ(?B{BzDe&mB&~f|?+KM*+#|)zO!dR>Cp`)Xpg=IC`%Y zG#n}jA2*o|rI!$`opR&OmO(NeQYgo>7dCKBB%Bn^EW_ zdTcCQktwt<>8=Zp9LnMMs_aU>pN5IkhcQJWk`%SNf&$=R`!FJ8Ln?sLFM>B-j-WO z1Bs-^)f>}FI@HU<*pnDewDyTj8V(*qfQzDCmDdjxPPOE8o1@Pl2NDPT6@SH!g;L`V zp9(j8gFL@wbFpmYql-Z-xAoz@y8^5zBynQHT~+;1X4+5K*po!1wx)Z@A}mdrj5WN_ zX`+fWy;)<*5+ai1ovKI11- zNAtGJCn1}Ebm4}ZB+Kcl&?;Wv%ObLqjp4$}L?|^f=v?Vh{f5=+f6uGyBW}4ATVXlk zOm9xrU=bH*7nk*qGMqX|7XG=GFweKf1oUg*VAe_PYh{eW!HZGi@=q;xcBtC z*(T={E3)11tK^O*W@$lZ`Eg5#8FS*e=HxPH(%_<}4r)dosZgSG%3tf`vNaWRriy$n zwduLm4Y($X2J4M1u_M;iSYX?W{2b;m9M8*y%nhRu7?tGB5R-^OB{J$^s)Jm(QFcqm zZ8a6DgbZ#K0u@rU&}_rm1GvGsRb-ART~{}0ap^>SR-O7vv8l&T+{0T})x-s{B_%E~ zRD4O6HB2HN0~WRe@UFyE{NI<7QA^-r_mGRxajy68g?YCM>W!EibcXG3+eL`OHi9cT zna7avm$SE-qKA)SS6}r*zcMSE3{#VI74D0Cham`J-yQm_EYIw`ajY~oDChe3<1>A? zFfJ>@p!v+x1{#?3h2m?lWG57xnMk-$YS}2_Tu=SOqg-k{lRrLQ&P9z+w2hocU9ow0q*E3z2A0BE7=S94+gN@db?PMgFWw*fq z@ePAJ;^yG!@eNSD;zx%QLRk&?E&o9gH-iAsY-M4zQM4diEn-)oM<+TMS2^EnKqAsO zQ`=7=V@}z~V?!p>;!RqA9yCD?7dngG%Eas{K|g16)d5-xHet^^FVFATaI%a&_x{+i z(}8hO?hwBZqs?j9KAyc{^`-n?m08G`$P&Z7X&LP8nPxnZhB5?O95!XF97U@~2`I2Siq0ZJx`E4%USJD^ zHW^Zx)Z@?3_o+KfB3?ptx^$c;teL6)E^)`?wTh%Bpk;yL(`zu5-km)60!`S@F{gDUCW;s0Ec=-gbra1Mbx1-cADvn& zCR3lvVYZK;#^(1CKFhNsf22a3Q|8Vu4hS}c#`)8-6)>XeUMoKbcJ+mw{K0{d8nvE) zh%$d!r_GSmYzkIJoe2&z>(jt{8IjnSvJaObpG?W;tXhWaS7F`!QeYjA4YKr9+(gqK zs^2%llf>d&k}3L4g{!=ux1}OPQ@86INNh>Heo%QbB(%108>CY`;Vf86aiAt-PM_|x zG}N#;XL3W~wQ9~zrYL$_glN{L5{G{jEHSf%i$rV!8R@jlIf2o9oxjKV`#B zo86_!Urq<#He1`blbS*-F4~Fk4nnzJZ+6*cYIbSVJ9Hd@DvCJP9*q^89aU!=S4eRO zgR{Q{8x+d^&zcSY!@~bz;s3Dke^~fGEc_o9{tpZPZ?G_;_Pc!ET(z@|7wg}W5T9Ri zJMC3^V)n~ou)b^XKA3+})bz)SgTc(^Rv6Za&4nNvNps>k1K&igLi|nkPjq zH=DF>ks(LvysY6)KxXhW`nupiK|{So&4?_)kr4$_s+e=~O8ma9C+ak5as~?!SIYKA zP8tV}l3l|X9{7>myqTj6&gig4Yt{NpkTJSp0tWQ+HSJ93{iU*lB_g@*0#d`Qr;aR( zMd$faFh6d#sA0#DxN$Bs_c6S^n(SPP^A~aLL*^%G#ZHQ@nwRmOQ%jOG*i3wFu8lr& zPo({2E@Sfv@bG16@kb#{VXk(Iw2=C1LPNmdGhi{oBF($Ck zomhmB<#p9cY|E|hfknJ+q*;%SY~C^E=LO{EwI*% z(R2g%bwN%<(WEmXiBqYD_EsB&TZGoNmgSufeQ-69x4z_Buj)%&rN2xEYr3)s zho|WA6YO<_w8gsjEe(9%t*_? zTE{HEu8IzOFR_hAxA2Qt{PGQFFd_J!9fHcSvDmF@;QRf>l=iSBXL_bH@eAC!-V*b5 z&+NLhx;0)AXbygx8tWg_CcO7JA!G9n)?!f zrKcIqd87W;CB(A00*)h-f(JFq*oCY0_@mHtE`SHVsmC`Y%ZH(qE;3X-*~v)-eSHvX zW#Dl#9a}C6?aOuHZ5>Vu1I$F7)EVtYV3#ptr=?h>mfW8D1hn>Im$gWY^b(^IC|PJl zL=0NI+flu#sy6y{BRSSN>QH8APx4hDtQxD_MQcr=bdI|Nl1Q6~NY7{M&^Q>T>y9Fz zTY?;qRKI%2k41LdQbyqcWfHqe))Ig4@kORU|M|#vf7+u*I}<;NDLtzXz^QF_#I1UE zbUh{kxL>wlEdS_`_}cAC#EE&lksD=38Ks%0wh$bxcD`*@Pmebwx~_sw7%q(+v;vWwolE z$8W_JM>Dxpl{2XveVt-13uyup#a_O7AsBj-s=Q$B&GbIXRqk~Uf}_XB>>vZru12$Y zWhDN&F8|H;Ixi>LP+HFSnO-?LV#+P&b(^HsA8dc~Y}G5B#{KnB47TwVXBjQr+oC7U z>Eg@f`}DYB(DR_+cc=`2zd@r!=KDWkGQmRt3As4aJ0ofY}MzP=(+^QxP%lV7!$ZB?OCy z&?jTSY#@b>Ewj~}#!^G7{W&Ew!)2^tM&#SoORs}yZ&xzR?DPBz*M##^%+9W+c-kjb zCEdN~?I9P{r1i;Bdf1o&ZCWy>U2A{Eso?PmRHMtR(9!bJB+~9rETI0Lj?W!S86G*{ zB@=-aQ)*DaL`4f*{@ib39O7+|&pv})VcBc|K)s>%BL?PXI(T9vwI=-?SEFuJfu7bB zEEXNFD^$Ydsi$f{dmpgeNbHg`8_}-GyRzghk&i$Bc9~R3@ra2$^o9JWdHEj{XP-~~ zc@u~_nI}dgtTKI2x0y>c@#B%IeFMNX&le85Y6rrIMw7KS86H+f;$vF(HkY;W9W?dI z%Z*vt{#4=riy(p%qDcxYnP-rx=M3u)S6A@5t5!-F| z#TX1@Mblo`JsvL&C$!P*w+wi{heYcsz-W`X;0?(FuAgQapBE}1i*216aK;heuk!pD zS>;I-#%_8jnw-73s-ZV8!_VA*Ss6<2-WH`AEt}1f6|s1} zKFw#{bB}EPRoj}dVr!{fyj4_butzMy4Q@0jz1hk#ThJy_T)?%O{#i)t2kn6>YPnr- z2--A9&z56~W7dfm9rlfV;9LBYJCTksX5sLA@{zJo8+$!u((9|J><%>^ZT%xa-ZT>p zVa!~oEwTh-dP{(CscbarC=7oldvzAsoY!28vfq^3rZtFqZ2TXT*>Y_51`bRAO#Mb3 z!VJ;#{$jimzTGaOZ@lcZWtyIZ2VyOZ7~msBccwqhZSJ0VLWPmNrIwu%9m(^=Z3CdD zr1woF`cUM4E4(nxKs?GZPQ8(c;9-iO@I|IbF83xR%s2Kt{&=~Xdo`> zPBQ*;I`>O1TyA}S>+Or0!;Mw7<#uTQkg6}|_iay@GCCyh8J_}ek%R!RT3{DQ8oeok zr>&wRY}(t9-{m(#)xBNx9r*!Wy(6J1#4UR>aQ#{cpXGtlxbGs0%Q4mbclB-t`_I$} z2cUTZmAMq9GYk_l%p}p%A>WjWlKw~~ZBOs#M8wgP9La&by6}OPrC@{3*AE|?{&^Qf zdQT*Nq8Ej&<{#7$RbuOd5F@D0`4Xgb777R+zGbi|IP<8UFp<|vaEcU4ZFDIE>Z_Ke z(9HB;Uk+M+mU~mM-w#l$F}b}Ln`8%XNxWvvd6Xd)*)HV^~+ zl^0HElp^149;fT8B67knn8c;S0YY$Ey4rO#XhB9avYc4mN@`HEUsy=MLSV1V@2@v~ z`E*&m+oz^XxG{l0hht9coYW+5YSRYZO>uqU1h1bPjM}j?{c{Y zd}nSJyek_FH6sM+1=8~W9>!I|~w_w%Ov4f@e zOIGmrI3nYd9ZeSFVl$4T_aR_Q##C8t>~}muO_F236b}(PV-D*VtGb{fogC2KF>S<6 zl_Qcp!egZ(wG*bA6j}2wTP%v%0yDX=|`zyHa3nt6b{_yF|K=TbprxqIU!dO ztmD9~g!m#XeG!u^=TC9pulc?4-5qD94QV7`22iT|8%I{>>u)(Y za@>+Q#+IlpVV`;-3!do~7L&tx zLJ_T%&m5`CIMmY*4^R*_DUd18VM`QL20HIvV=eBlvF)%QV8ZjunroY=XW90LWH^zF zP!|1}6@FTuZp4bA-Gr5)H00*W(^|Q8!zoNG=j)MOuy_3jH9Y=h^P|dbnR^rX7gzYo z%=;7f*v?_l3&WBQ!28)6XWvgcIoM_6n(e-m!Tp|l&L-+o9}YQtUbZVP+UHn+4al5$ zyKe!uB9LrQPTa=R)RS*Y zE^8-bJ>d5o!$KIJy}7${JO(`>x2%O*b<1TMPSTI4CYQEp71zh$JcAS$XQ$6xwxC9j zD!SV5O0J(9K$mgd@~F}EMp#Z@82gTXEGk^=c~dEsF)RkgwY83&KvlJHg4k3fDnX6V zrs8r7a~?{T7%FNjv|HTo`fghH_z9J^Cbfcx<6crb!rKp#7cCclnD5Fad@wi$%!4(f zxNVqc8*{U8SH-7y^B`0@QrAD-Z1{V`}(IoMX#R_>@#)Wb<#gX{L<<}{QF zNA=%=cF-lvl}L7Z{pesmX+7*UBd*91x{-;A+mkLnJk4U&`jryfrVROk+8t@rlY-)B z+KwL>8mi7Kx5sBlQY(R9)A!5oW_!pOo!l&PntyqSMySVlW*AFAV0lm*)Q+jOp(z-; z?VrtVSn~NrXT^rAbh|2~wM0w!og|e2Nd$PzmRXH04}C9G9~HmLUruw1mn2ly(w_d1 zGtV#8trNGx6nK-4_H^|h6V@+na*lfaYmSjL#tYjVRL4BXOxvVfFh+w) z0C%=O3|i8VD3i~8j@*-L$O6m=)-lkjVf+yabn%L0N@TLKp|0XvJKM)DafBD!Hr%&J z+t8Et$oVb8EZodyWPaQ_Vn*91kT#*F7b_Y06s?~VXmDv+&aF z?6wU~2wHB=I$qY23e)(h_O)D_l0Maafw?85Fx`>z9sejQE&P%{RYhnUKeUVW*r;P9 zasM2g|N1w~gvRgh-<*RkI_~*r!Ln?495Vi$XxY(wbG5%)uK@Wwi4{ZaQAp??ePG(i zrWWk(5i+ap6B59ugMC4lGcf4qPGVl7|i zb$I+^A+@#sz%2#k1I%uixhO89EJOhSXC}wz&)k=Te#vzwC3AslRkK}bSDa|u3D@{| z6@<39PL(yF?L)|jrodF$`zZKr6I*WopdvnRUHM zFgf+T7Q}d6XoR!fmt57n%t@I?`rYs2-Qm^=?{wu-mx8?G2)*L=H4pK7Dp`!My%{sxS*0of7Bk=sP z021F25tb(dI)XL}lrZRw#^Bi6XmpkhvnSz`Jvmk8rp-VuCtC0%a>Q3{)?G5R_VRSGw=PVVhHZ9~`mx(;+j-BW2y@r}> zj)IAva~_6Dt?p=K5vBSGKEqYE)|xV;RU424eNn18%F^_SIos_>shpmVou*z8K3x&N z9`hWvVE*)<(^V$0ViU6Bq#;^D(2;ku^kX1WJt8Gq&abGZG&Xl3mFTeuG!*A6=BXNy zmJ$((1joDVVD0LVMN6JvUHW3JkY}GO&a)U04HrdOT;W0Yay+sFDyD(L`f(^C=ekP2 zZ;}ddLLnIyb0}S@Wz;xx4#!Z&>HXQ{-o_vPC|0^%Um~Do?YFp+t)popjfV>m_) zD%1eKvqw65ebhzfk`VuDRXe4%qnvLp#tLvEQM4<;cjDi-UW6tjD$C_EK>prr|< zI`(UcMqbNV<^2 zL~A?o)oVRHGHHR*^L@`QZp*l6Bz|X$V64{qD><~D&XBKkQ!(Hh2K+-a<#i26Tir-w z7MZB*j4vK-RU~qYjeTp{j;bxnxeF~*{Km=0?evbgc3x*Htzk`%+#kQ1HD%MO74u%( zI+OPMZO)D1SqCUt;9 z4dnPn&@u7Fl z0Tj!2(o?R6Gj=_7SmtxOBt4@LvM|^I$N4I>_sXFKQ)&5p2s0KexB(Ed9*s<(JkyQ0 zAA!`73vosPmb3U%OxnH)FqPC+H-UdPC1PWA47s6iz(Z~qREr|-xG3$QOk^aa%@#SE z-^sD0r3YaooPM&4W3RMb2?t!We{Da95y+i)56CMqgcjUXPZvhvN^IhePcBHzb~zrm z+UeFzoh5SF(RV2YHEfshm`s`3>v(vjOK)X^T7c=cbSF5)5zQE|_TC?OyxJzHhgpa=W^Jf-!J4 zNpu7~*+$=xcKw5e1|u`g#3fz;`A#NqRfl>Gv@#^{Iw7O|SdroWzZly`q-LYj<9y9{;W^Z>G3V%GIm2 z7~vg=etMo(^{e*gQyG5&fPbuI6HJ!dAHOgzOv_2abDEUSR8XvANjS+mAs~msDWU!5* z#k+g6dbk$RUuw3ttDT%lQ>0sXb*(1NfAGy&?BUa@{aG-{eX84v0g)$-Zy<5_5|vu; zch0Kap%R8ufMfFWg6Ao%fP!@(Z z=N7r@SkiLR^qaZs6Tyt*bSzx$@Dl#cRu)~JG`ZBqmQH8@5dHbGVwbDSjV8k(d>P}Ug6|-@2-2fVYX8!AGG5Ru|+tPL#LXrh$$@!ZUo?pyi8iLkb*R=RK z;}})<8oaj|tgox?xwRz72Tjx7Omp<$IEE#zaE)D8@YdrhB!sfT<8n`yli13d&;1NB zaH}cR#y#SVWb~W!6h3(G)2+ryuVY+y*g_A-bMR4ZM{&^`%krtMw>D<$q&)5R;3rsO z!IE~&3V}r#OX}2P6X|cRQ-15q$hs>GbfDkwX{?BEnN&9LJbUZyVJ6{*IZ)Zy)~|J{B9AXl3!->761$5Cgk@fg#YrOqX$=duoUNUKTL zPiwN7(D1m3p$?q%VH+{V;&)hs`xIX|p|AB7wR22}jMQ)fr>UA0$jgg4`4PP0%#v8N zdTYE=f#Lf-*}cj-U?zReXYnok*e@+H){%w%Kz{gwv^5lhz!jpHS>iLFl|EC?DFu|L9O;s{IXY^TQ3J8M z!{NvFp_iZwUmr0h9*TqhK?RF*cT15VF(*kDlx`K{!{2}UsD00yYYrq-4nufy?p$6# z5l7}>C(UVg^}v!(u98=iOI3~=$ltn{|0$pP@%|V;tyqC{k;*u@&|mM0zFzb3_Z^&3 zH8j_2gz2hNu7gQ6-8sgoRA`wGiO0A_T?WlvE4iCEdkdLcQ?U@H?iy40$)`vO2+s4u zh%~J+giqr1L?Tw#31kr;&ECIwfq9DFa_EyvAZN-ATXkxsKk5h4P5(h%Y1Eb=iPxT? zG-59}QL(1@ESH~v0D7FxQ(!~mDvjn8oVW_~pJ3Bj>iQsc9t*Pte@NYKNTMvgeX zKU$6)H~g&avl-%`z@w<3@19O0ryR=6p>O7c;<_2>oULsr=PRDsqn@e{CQ#xiMzA;0 ziWrMTGO(xqxgmIjlC$i(M~*MkP=#c2XOKJ^Od|2SA#l-} zbK6M6amvwsFpPoposAZPA0S_jt^;UpjV7znu%k(ZY*r9dHWb!Yj1`-PNm1*5Of`vr z#eegV|K=h8%|rgb&qMa<&*nS4rODv*X@WMsc=?AGktf;Q5-LtTIFU$);(LKvg;=*l zD;2yHBxL`HC>prG@=NpiGca4;TzA`_SFS;H7@?G96GjYHoP1Bt*X?(*bIlKk?)2{Lvo8(U!fN4drJ zO>$TFNcFT;T0)ZrR5dzC0v_l08Xb8X7^%z0$G9}7Dc>16LB~k!9XUK@1UAHs&w`h- znV)EVrF^1rC_M6t`jQ*72^+smBkQqWwf3w~;)H(;n&RwPt&!I|%BiEBlcCt~R6M z&ewwd^5v*}Wdm?aQbzN~*g`D3bJ$JoSWnD89YIwafDqJ>|9W$h6(-j0_R0 z+c5OxmES|#7u$oaD}T`A+`hMGeTgvEt_j4LPMrhqtEuVM`n(PQb*W`Pru{YVs|~OT zs0Dsj|5*hr0AY3bz}c8=x#8mNuPTV|NTRI=`GKLaW(Q|Sxtl^J<_%_P@aPw_0He(4 zxL7|kU5Al*xX{Ue8_!COx;8i^wVlgn?pbQU7Ou4eiLKMb%(mFz+1#0kyHyzjy6>7a z@&(DF_w66xj;zo8{Y<3ce1v@*!f$c^s=S) zt+P z`@LIPkyDuhdGS|`72L9#(6OEd?tOyQr?B4SWw&6PWhGk?=_UcXyjq`U_nkc++yS#i zl`_{)-&TzEX)A!=5b@F|OJt&U+>yWq0OW5w5=zng46lyTf|*ScHJ99effz7uE@~Rb zwP(@8xzKABz}H=T3qvS*QI;m!>4Z}iMKc$Ing%P{<0I=&t{q3BCJHFk?H;Q}I?;%C zH@6~pzb<*igcUAd?POU4jbWr)8Np#YnTt&ny;h~GwwGf3-x~TUBGbFa6HEu{7)6Bl zZ4@anW_b9vf^~Q!aDOPp3HcLk?O_P37esex-XpN;+PAVD4ZM4yV#i=Hb( zv2ntN6Z63Fhzv=$gWuRc{RHQKw_UN{3D(_36+5S8jYUEbh>5<$2^{@1Sa_eb&L>;P zrMA$$a4~*woZ*HTKk@j5ZwHs>grHGWaX2PQFDrU#OXaKP(np`5azm-q3Cc|lmOJCI zHTG}-|2)5nPJ83j^Kp=fgT9k$wN(6v#qLB}UifKZ{d4)iW1)%WJ8O>zs;53@v|aj* zrHCw^dL`4Zo%6pb^%PeD#w{-;WzteO2toEJUjW;~BToS>sw^L9QT_))Ck+gS)sLcS zYjZ?^37jKYU9DesWbtqJ(rcPB?j5v^2WwLM6ZfvRdKVY*qi(2a{kO~h4sWLrr-m`J zl>3W97axd;nErs5KwFM-#w!7Gt;w!+_wGgqV^-0id5M+z;xJej;t}J`FUG~i8WX?i zI{D`fHyG?S>@9#sL~3|uwkTU98%*al7QZgjA?7}AQSVF6zY(WQS8t0w@86)J#P32C zo}BJ**RZLJc2&b@=}q#~t9%+EREFmPeyMxYsN&K0WH}Oumo95Vm>vU`Dd2XQ^}a^( zAQM0{5u-|_H0C9?GnzJ9;1?Z1r7OYMlOSGq|5S*i|6V>z1DDwonpQ#o+hB1w2M*Ps=8Ej$zV zidc@pj7qR^berHZ;%_qO4aV_4RUjZo+XzeM*X@Vrkv0IuEO=yTiKMn1I50o9a`*8{ z!;9IN36DB1jO+j`wR9zqZ3srnQwHM381Io2eX4fr2rC|#*ipJt>Bok=4RRqln!3`5 zuv@iTg&uWojlfJ>Ofv>dl;d&gVdWahk|7s|ukg`9EPq>qV%bC4;@Xcd~ z?czEG-Qa7AkIWLPRUw-QI!y3RdHYG@L(Pei8?dS4)ej8n^vzQ(W2qLD)Q^9ey2Yna zD; zsp(SofJa#BC|#2Rnm&g-K=_2f-ydp+ZfK`^Jw}VxUyccOP29D7%Ii*&?i=Ex#>Flti9j$ zJYXo~Z+cSi!@WfVBO|01sr>hcgsBW^*{HQ9(vIKzA9{rc#WT?o13r@QYW@n+Al+mw zKZMy>a)o3h*Tbij}^ZdpG_7hc)q zGP;jJf&F8#QT(HD1|FZDbB*>wRkPa^gI;xyh9bcQnxkG@!XL$IHfa0PmQMX@=c7@? znC;e}uJdw4l=KtbXZkvod#xH2Qwk!oL^DLfrIJW-NP3ZnXtXB__9CRSAsckMZx~eK zVi>~B^paU%AHFAa$u+Mz5cN#Ry*~OK-noeE4PN$C%(wYn3r_~o+iFN$>jY9oBoY?< z!E67<89f#eV_Q6qR)n*mCx-{zxghmtt_LYEJ}H`~bvZ+(Jrq=|#S zr&bZswgJrI$Kj3A`PRzZMn{NU*shJw9IH|gjcc|X4R|b9o<2DqT$j!cX2Uw!At(nP z`qM)v*^68&tAA|jV1Lt;Xzfa0uki}a5NbUMe7qN+Ma+*PK+OZ`;NF!!oO9u&463$% z$YmhJr2GsAeF+%m^(Ef+V-II3A|a9VAB2(( zXzUU?7U8%jMQC&{fwU5~s%RDA3|^`2;gZz{1)(fc_%K!mq&M}_Oe6$|u8*GsqpO7e zR~_#E-18RLRUddPa0V|7JCed>DvZSB!s(=pbf#&*?)`46oeuqmfHAUN=CXQyAg^du zyN0s1gzeNzYgK00glQJ#Zkcx53@G+~!c#3BTh!404CZSzOtpA` z08xYYT$Uz~(LNKIXmFXjH4U!39R74;vfUrO`Z~GRP=C2ocW-4>Ue2Sde7_o%RnT-= z8*AecFbazF&dP6#-e5T8CQrpZuYL~N`q(I#@!d**Rim|6fS#`*X z@2I3o^Zvj^7nc<;qc_C~dxMBwmQ}C7@6%IgNWSu`H@mxsShVQO=d5xIjgcXcC{ma)xTqz%Ih>{>nvl@-fy?ZtMERBCMA|pSydJ-m zrllcbZyihlN^1P%{_;jAVFq$EbUQqtH3R$BOnfC?UMHx&nAIo#q2) z{$BTtrv-9K+JE*EcRQsyP7Pcmyg-fF>ZbEbM&|pN+~k3<6aixwivS zbx=mQA9-=Z>0uInkmJaV%dXu)X>#jZy)Q2J8jiV!oO_+aLPkaTTWD~k4ftWV_W@j4 z2g`|DA!q%Gnq;G9o%pwLS)^7SQBvjJn&p;YDy6@1*{LW|sQCwxVw3!F99LCoWfumw z6&Ob*A*W&I*gU`g*5Z>e%((iH;?`S>e?7KBITVsA?zp9Rc4M;`EnP-A#$nfb)86!4 zTvV;GZJmIc+S#d3+C_jJ_)$=Dt?aP@q_5%9zY4iINs$mfGp0l>l~>u7*Ere#{Bf(X z+BA_Cx*KWOukaHj2lgdQn~()ChGtz5dhrrQ=X zTR^4LgQi7jYtlJ5KaBy;A{2cTpSjWFM!M9Ir`lw#dYE>NNRnc7aGeWSEiZbEUgfpq z0v?}W9VKH3J3<>Nk|<`aSM6L3!8J);>-3F_(5#;?8EJ-GT_B1# zIn94y?udro^*_^HVMx6+ud!K5gig5Q)@c0EJL-Q{J={1qQW%rHDOmg2uu0>iS<_Y} zw3_T?bZ1F0KRJ6*=k6WwS(0{133z#?Y7#@%1+D$fjm}Ont|Nz1)$658@H;zDT2##B zEp-%BPV2XhSs1 zeX7IKTQXbsjn_bZoRCy5343|~6=PT~={?V(1R5S59({@XTD$kW|A9GRld?&rKfhahy)V5^o+i$Vo@ncGq+j2xP{|jRZh$9&}F)tonhxD5wozWj-^7W%H3gN5Av+}YK1tS&n6x2rf7g2l#4oEsUk*sP(v%e z^!ud@#o{&BK;)vX!WcVJ!`pDL=j%8#1BKlFZ{W_=Li*tA)M#bogh2jL9R*F(!IE1E z%HZ)i6*Jf0`%DEcwCbj63a9D|OG|$X>-N={7>(U;SK9mg7)-hq_DdwqJk6>-z$vq4 z0;|a17Nv44cb<%|+Z6-yy-FzU6Ea&jH;LxU-|y`inAMvXTgzs7t&=9D9Ryx&>b|{k zQTY^lQROMYwfJ_gWS}GFQAIo|8Y4Zu4VB8 zCm|`*PLTaAL_s8o0xRfIHzAc%?ul~N>oAW6B&`(xAnS_5j+5cJ;CVFzX^;pFK-)do zksO(T)G2JA4$pe+la6`=%jHQWyQr$F><8QOJq2o7$F`=zBL?Hg8<4tw|IVBOF<*xz!(~n!94^a_Z2@cIU`vb$>=Ij^`SL;WBeJcT8reDVr zI7qwwM$F14#G_>TY3Mbmfh{2MxM3#%fW(Q6SLh{7$M65P>G*G>NcFNJG$@#?G6Vfg zp0#>ajdXUbhE>v(Xd*9y1vLmIj#5>hso zdJ|-vjD%0lCtvDfUaq!Zc4V|C?JcA|ca(jiqtD56#-X42w=Css?4mb)@{0pgfu}&x z&W6mt1OD*YPRQEm!OD`&0Me{vKeI<_pw>}T*^EA~S?a{OLbp|?0~gLZXi-&q>CIF3 zUroZlnuPx^ngpN0x3g>olaU5y*IBC*@+{FNc-6#>0d>fiRpgKXp(9I_KyS4K%~Bzj zLaKjYGI3Tu*(<9hxKSUf9vZhPi}1WaV~ujH9y8KO%d>Ron_YvWp*lsdfcGSlDe4_J zY`>YTdo*Lbf_+AgJ#?iW^O}y$pEO&JozSWqp&kJg$&ehal;(yL#gs7cRZ~4GdzI(; zZ@RJOHkmbit4R1^4fA?Mjwdrf7^I*yP4|Lb7p`B#jyO+|I{$j}tf_KBqb^jn@%1*kOrA6X>8;cNo&zR*2aQvBS=XBT;Ywrjjh@AfvX;$Ks|3ESG znI9LkiaPqE`Rz2^JnZ;d%7n5fz9K=X)tBAI#nEF8re1a_Yl*2A?ytJ?yucc^)C?Oa z{%n2H>~BXwUg84-pkYl?Ea(U!L)x+m1;Sv5$`b5_gl?BhEtlBI1xUhMQP>4bvu8*? zMi;oJ%|!M)y>@927t9L(lABUAi)I6H6;gqLd>zXVl2}TNH|oWu)5^EqJ;l(}tz8FOqyZtkTp8vppnkm+2+?1j@|Bcz!IXa50rRtpd?HJ9o{)p$u$1sYiwZGrh9x?7rMSe)H zostJVJWa(~SlKdv=qfTR*{PRz=bA2lZ-2#CW;sWlZLEt|ig-2L!`S;rXQvwm)s}f| zirt`Ga5j^fvoHW7wAR*)`Rc@?MsOl5fooU8;JOX5O@L8;jOq}8Exj5y+MBD{CFot{ z@)^|Gc3u)2RLHC$Trhq#c{NqbAjHnYW9gO5oqnf1N!&jzeMv>ZJcVhb=tM*To!fLQ zNlP`9=8iI7ku6|S>J&?EkoEjUMZ#AXL0cC`gU@Vr3}Za{ft=xiDBhwtrRmq3FCs;* ziAhJ00FGW&0v8sgl5Nb=`nIBA7TkuA%1+XbxvUIa{sx(%GQ}@^Yt+ioSx1%O*7hYI za+}Am=Og?>)YYcd?7s!bvgHp;tT@HHISvF;9CO7ccUbHb48^d@ytqcv5G(X(W2_a3 z#wD@n=_T>h+_r-88#f>IWE!y$e3(Y!qR0BB@)8qNGGMN#;o-UINS=@crt{Li!U75` zxm#5I?&^Idg(c`{g+3SPm46}K7((1WTr_O`{vGzD19pfznJtrUQG@f?9PHkVD&PD% zofaGCeXY$E=9RVxobT*TYBoddrfh5D`*2ojGKML9#>< zV}+W0cJA|Kevp-Fg?Gh@ zE+fLqu!Y~b%O<&4YO@qX&&SGVgh0+()Q!$d!uJXs3%r*h>kB;@ER~iUW|VB{(-R;N z7k%U8k+mNw{$v=RF{t#4)* zo+o^XuXWzkGMU4GetW*D9ff*|2$@isrw-r_50(f-_?)rhg;`p#%CF2BR8ZhkcF}Dy zKlI(*+tzoz){P0ZszJhqCfca*@X$gI&KIpb-w1J0?PCFUlTxs8Sc_Ox3w_3Jy8HS; zc2Ml_5n%f$XF04^JcBiRb2!l-{aUCVK`<$hQl?U*^=I4Vn{oVc%v5Eaa8Ac@PRz0u zViwU`RAbFcac-N-(ettmRvNBoPeXe7X$)HB8 zmt*n9M{tdnfBm)%lQ*t)p8z~hE2d^}DMFVcDv&6@HIe+II|^jJ#@wlRm3?6xtWd+U zp5u%>IT1^~U3nodk#d+qO>guyP^Ie`f_{s z)vaThV_e{w0k*wL@!{5354_afQKrV~CQj$Z>UgCOCChGR%Rp{nDH+)6!%=I+?)oJz zEC%B|8!tD~Z4Wv(DQ|uj#UjgQP+!!d;KheB0d zmNj)oZHe!drn34!FhQM$Sw;H%9055Qc&zHpYnb}_##G>OC@x(4!4eKpaxR+zwSPI4 z;49X%b5VbwDx_D*zCT*913M?@=ZT*ZdotR| zD?_E=OHhtdWzJiQz-P0w$pPb~YiU&d6%fdX&Xk+=kW)RhO`*}Lo|yJ@p$fWTEfim~ zDw7|~>|m{oN3c5F&$XPk;D;dXI@-_U&hyjA9^vnapnx2SES+ENIKIJ}KKi;t($%tM z+GmuMy#}foNawFXA7T*QpP~?IS6t{L_D)kracMLwUH8?QUkEmSlb&{8hq0~*9~?KI zDLpbgxGBnZ_A!dn=~Zh!6NH{xZ49|MuGU(K5UcC!7rmU_pBPL zR%04qI~QWilR|t_y<~-VExJZ~%K-!>H%&Uen75`^A4ZM3iw2=sfHBPIBV$ws4C?fl zvx?A}a80kcZ^3Bmq}|v@5ds0{vdC$fcv6E~m@nG%`ycEKI*%0ws}Vo@ld)^Uw^$`Z zgf2hS4h1BcXX<&}vpg=OFp6$0tR>A#)P*TYw(I_3e<3RsvPrZB30-fz$@XZ;>J&^{8|-u^`Xa@&x*^f{quJM0zLv-<8qbFX}M&Z=C?(l2fWRCTJfo&t_T_* z4T>mk)8P0@KO7Y~2#U2C0@6?PTKtcam4DfJ|FZM`W#|3pVdoL8V(^~jrc^fxL(=x& z^=S=&v!5qPp+dXDO3orA1lM&(wqT!-nkZ0=NL4PgXwPz$#ZsnA`0;jqo_9>6?wP7l zd7PJPt6g>IwBgupsQ$1`8@T!wF%_Tm!dx55R_=f?om~gyqg1w-+-I<>-Ax%@((;&AcK1E#X)N z^SHIT*q?|>$6L$oK!1wBwESDaFwJB^z9*;fO<~W|#R^85L-T+Ot|S1aw;RCt;7573N?<4OLTNxCB9KtFybMb?EYdN!F+#d5aw;2VfR!n=tuyb zZrs7}j3)l!96{mV@|%f&BIF|x<7R;<@It7QJRWqYz~|@P(lJ`QKqOaZL*e+)LNN;B zz`ZKvjt?7Ul; ziPCJEzUEz+;&}{tMFbtnrD0OpQT)jfy=w^ZlHpLBTPPrEG(WP?5hX^-Mvre5%c_4S zf}U1GdSFQm_wkUA4CXV2BcIfF{Ny=dq9|?9YN2G`-jonm`jI_fW)cCUsw_vKK1@lC zvw_wooRu-yj@r$)9R7BafjX9-lf}?*uH^2$ORvVTzc89sd>!dZ>8{s!$ZC=(W6y!6 zs(i1S)MERnwUr?f-ro02JIHFRsMls*8@i}wr;P?l3c+^blUgBAgNPedI|8t_L%Beb zwYonyqR4`DGDnZK^pm7L|AE;$YBHFGx$EE%T3Mm^)Rfe6;g1fHs*l1uH%#gJ2L|mN zhKH1hCTN_6UaP-0;)Y(jSZ5f+dlpYRo*}NY7e6bP4@{Tkm-WXLZWX&ttEzC=D%ZnK z3^`~+f_JiKURsf_s*@$gbP*~Gvs~?8mlEP$aV#lpzBTli>yRvJOR%8%uve7}F z;hnnDmoUiK{7K$)IKP?aycq5WN-%lcT1tM3skRY)5Vi5q3aeaUO;KG>x*h+`)*sT> zE?kO28m~kNPjDoePmLLYwcX7;mKpR zRIf?`G+dXUJE`^!)iW1h+FAn*^t)c-Q^eFRg>uAc7a9`dEh$*}B&IOAhdNA2V;DDFJYuhJW0tu&go<#e6D6S~ zN5~l6YV6-JqvHm$l&0H6Mx9dEjP{RPRv&6wcMrLR8N3LC22o{aiT_+`XA!`N22wkS z3dl|rZ{i=;9MEB(u2lNyT0lSp-F7w2!P0rNtvQcf9HDfnEIjkbZNPLxW5sSVUUSSy z=Ds+80q2tQCU^Ik0)iE4kbxb6o%3O!v0(;tW->MY|};j>Ef%YXiXksllB zzpkIZwju&C?%JM=@F{E`)Lo7rHD?Cp&dJU^T!!2AK1K^tErWE4$4Z>WH5nwctuYP@YjBAch zWa4rzo+-mqraG;+uf8)Rd*64rQdF7~0Ua_bgklt5gVOX1v`Y(rtg(1Y z^NtU&syth>vVTxVshj4sh~>k`+UNe;T zS7|aU*xpW(k%4baMs4NEmHgSd{LTYO3{37*a)JGN zd#~0b=DtQiSDRd3#t=SM!tLEQR{KP(3Mao*qtgg?WI;1h&6B;Li3DU(mg;n!kvl@? zpSSVR5hE{QuCx7OG4I4Yd&IP?!tgO93&mHE8TkY;1z z`=pzDHZb0*cdDJQtMX|{T5`<6mq|*Z^~X}>yq)3X8X~EX!gZ7oWmo07N!FHP}qX53U%#sNK5sdLSa)XlI@` z0p8nxuVqD4(0B4;*Kcc0A83)rU-R0GuRz+ZGSA$;#d1V;W*Hln$eT_-QRcShBci94 z*gT6NG??!pC`K{eulH*%enLL`;SiZqf9CL#FF@2uMTt^uZ7}g^inlx|?lXD4pe!c&*GrO>!2z-yB#z5A`^sd7mLC(R zcG_cqN`!U`5}MOfd57O((UVvXN;-b%lz$-Kt8>U**iC9&QAG_vdVl#d8FYDvO?vmX zu?dT69Fl2-*Ha0DPf1YioYl6z2#AaGx_Ow6wMmkHP#Vbgz|9)=DnO)&qzTWGa5}Is ze!pW}CgP=A%MC>Siqt!60q|~IH;Zt8=k0Y)ni^P51B+Q&1WT18w)&I;Wdu3kc&M&G zd9JNxiVVIr4TOIZJ{_8=-)ydzfonUW_Pjy!fF2!PwMvHFzp_qP3<>dAXdCp5o(N&>L3+jn?vznx8AtaG4T1I=qKH%dIEqq2*)v=lB zodl6}5Dwdct0yjs=NIIo)fDVHF^fTbQQB2=GtKjLRyg@}$fc9-9w+YWR&}&$}TT zHoDZp*&UCDe=;8OnZT|{AD?ACQm!%rno)mOqfly3%*QJE{kQZ3o=~CVe8h%JrwtNS*UUAWKw+vr)tIUhZXWeHN8tYEI{p<;u zhK5x~^wSsVMF$F2&+9n8b`G`jq(Q%WhPwPyxFLZ#da0NXF)plr}g;h^kD%HDItW>F`5Bu76;2_3^EVqQ(*js!3PPW2Cj7 z8uz5!zU_8RJe06db+zGCiQ>`56ICC7Oa4JxQF1l)b3TU#iDJtaHa0=jSd(RvI!)*8 z$}!apCGLW$=vL8Dya=yq1sdo%UATs!lZfc`d)R0!v;!`Yv8>*YiwJx%;4k^r7e z5xY-%TnH%!!R!aexo$s|Ry<#ZTcgACmDYrE!bM1<-2g0hZ305Mz!po=4R)PZ$@Uut@BJjq1*zK%<_Kim87xus2~=CG5L1Z{B9G4Vz)SKLo0Cn!S= zoO)j!>bVQQw1H>*Vy+F$m_CL35{V}qslk&>4?Ba@XviU&fcMg2?OeOrYhNd4?OawE z1!e-EdO{84=Kfov?@Dt=GIqch!uqLaaVB)@=_8Z%K)hFYrrPp9FuNsoooDEo2mioS zgfV%w_((;|XR}9n58Z6e3F&w4qg$Nn+K`mbj;2dBOQ}RT27zU*jJ+6ut5%GGfLIE?*~~Nr;xy)WIg5 zV);ZvL5%W-XIXJQtb~{`{Z)48AhL9bGe?PhH0A^XOD1-1W4&0hxvkdYBo&o1P-V6z2JMtZTyPv@!bHz=IDu2!2^t+=$;B(k%P;*`_7Q zxFPx6G=O(ylI3(3NL=Zf7Wk&#hZ^L0#VA#cO{5@n*m4(`s}v@arsG^iD|3E|0&Az) zq0fS>D05sJ-Hg3OY7f>WqKGf_=mesdR15kv6U?4Z?rDAQl{u@E`d~vlisy_I18Fov zK&DqLtFQe=1dA%nLTy&b3gixC!e@j+aP78~&9z)G=*2Rf!3tDr+*CANN<`5c)&dX9 zk_pcixJI-}5RXKE1W}W9+%>=^p3un~ z3_aT+468EMjfKl3$`djMVU& z+T=46T^F0qRWvdwF)tJ?3Tk|#HmP|`5Y8pat%@^w!_)}+l8_k_Gn56W?X&@o`%E3n zU8SULGK6f-q(Q^>+ZK#n$i@;=-9b2aO;Ad0YI^rBJ36I$41V5W3Yw4=NpdE1F#f#XqX3$97R~{IIHz_n*_SP2K-X!GOCvDgG z6-_tXk`w&#z!Lf6uG5S86`Nzd70@PwS4@w)*As15n{9$`VeS&W$2Sp7GT+ty_$vRBledG8Y@}?0X7Jr`b^+eG< zorkQ9wG%qhTy+CxDTgmTU^>$o@FSy%Usq8bhh2}8ldPm~L**>x`a?$4y@NkTvD~)T{$6Usy&4pUT zIZLW^I5#^aCk@5yL22hw_N%vD;=tV&uUl> z+6;s-hzgv!zm+?3!>L?Y+Lq7H5nZnGhBxA6i6~@{?ESv`#d?_&gq%1=>CL_|7?yDe z6N?(&!W613?qOM%I`=f4chT0WZ2JF{zqUKd`8V@M#`pNwMtkm{JEN@91gGb-?j^=_ z<2ReMEpM^1`AH$U~ zUef4>g$Pc7kS&jVz0l`A-=6VS^`K*Fwa$S|30PrewipUWrB8~g&N+^$#754eS#SjY5b7En=UxzExQ5HtOodHes8c?%?8 zIw!s=Ji!V)29I+GjKA-o{ z>|-Mg9g78Z2?T-|l3L?cp(FNFj_#*e^oV1UxNS_Cm_}abUy;#`bSu{*6@3_AO&P~5 z@H0Le)VAYK*(E4m;jCZ@FcGHXXD-)ZcUW|-q-iuH5RhlJn;ujoScN&pQXU;6eLFWe z`;&VNx-g0QRB!hy7v_u*j5mVZ+5wQr!9W?4M=ozXqtoWIzm=%*GAi95#C=g%62oUCe7?rxqGHLOZu$aEu~{;V$UmhhcEujnGb zS$rl?+mPadjj?HUPLxq>Go7E3=gX%b?ANv3%W+i$n%1TXx-JDnbQtC8(`M(DWIodB zR4jC32x@3t0kD^+-)?qbu$yf&-ru?ST`yKmpw9d<(|1cjwatA-v+iPrQbdolI z*ud%aAP_jA#WIV}me=%s=5ye;>LQ3eJN0Z+X1(m~vLMw}tTzed`iASS-SLzLpk4M} zWw&v&=s-pUwLF8|jN~(hNX~2Wa@K~AY6%-YSU4|EnrZw1!IME}`~6d4ETUBo%mGU! zLH6w@Km6LK965<&ewRB*RmW()2%9mtx4>bcJD_&=rp6A7L<#@}nK<#8vITVG|A8Tw zCzuL&jAgk0Yv&U0w~Esik1-;bu}5emv3n)|k&vBwZ40G+n&7+UCu@d9{Y%*SF2ccH$bnD42}Z`O*?pa$qhtZ|-7{C6=l?@D^1j*pZ`0U~LkF^7ubhji^TLAx z?R?~lMU@UeJt4KHL-t_aJB3lxOnG@ERH*?W@^q!(9Qma}6NbW?~`KGbf= zvmV>(ARRQPJMUl#`b0bKP{N!o{5k5q`Bf1(FQ^ z1EXv!i?f3KU~H}W!MtAub7GRTH2^@UX(rS%C1w~}%OZ|47U7MMt=@fVhkiM@tUVo` z*Bw`K`S|B+Y~`*t->gBbeKO3O$o6rdXuh>gh1}mDWt50ShhRA!D_m?t_YDI0)wndj zxW6{#n-8l)-yxZL^EImv5y&=%(-R1=>(_f7p}v@$)CY5ht6uig*ElzNz(tha`vF0l2N!R6y!TC)8OzUNqzzx46fUD%8G-Q`>fPgVVz$lI=vr3{xJhC^>5Jxp*qo(_B5h zz&RcHGG_~6xh=|71T%^0JRTyYTA0(=Z}ArC=`OgOEuvRE0i~XihUPhMjwMc?X8HNj z>t@EbGR27$-U(-)SFY-kFw@s+ZbgkXFK1V3DypBZA|F%bHTon6cpbXp+6;3Z4{`1Z zG4Pb)hzT{(p!MqP1e2Ixp?oAS4Pm6FQ{8cgSi|QhzFHghY#6l z2(USs+8S%My(!H%HbvA<`xc(9%ol~HyekF>7wF>{ZiP2V$Kyf=_*-8 z%qa{r5J-pg*`I%iu-TB2i?fO$snbsZ+zol;?J%3~c0W&KAAC$z!2+xu60i~*6wFMripaYocw4)R(mp6kSR$ji}4t9Nyd+@Vfj@0 zX<1Yhyh#Q0F2q))_CS`4zih1QS_gWLzq$e1p`s)TBi?hCuJlBj$6Bi7tE@UYj|YJ0 zJEYstVbZ!s0vumN9x+}b+VvlE*`E@W@!dt2yF)j+`{OHnW8Lg&r$1sjdvK&^4N{}^ zr1L@bqg{FJc?6L6TTRDbGHJqy_Jy{JtP1n9GVvXpf zc?i}sq>j~}id5EiK%JE0oF$gR2$wQPCoAnk)&Q}%%5v?SqX|Q$4#zC%DOa`5^a-oXG z&oz`FhLjb!eizb5H`LLWxil5w81P>qF-pbemK~j8st)uPR(Lj?T}9=Lj;_Wg`TfMc zAN6+nX(I@_#+>yz^g5;<#=uqWSYCcIBM0W9MZ{7J-e9tZhZ>^2D|TT%5Kdt z;}&Wg%eew44N^;=l{}v7EQYXKzXWvVXWM`AF<4m@7ms{6SxK+onueVP%QgX4YI?ac z4~1z}&_3kir$%}Rx}l|3L>HcUhI`P)YL)RhMogNx6;3h>rvbIEeYK+-!IUnnSHkr2 zc4etXrk2JTbqN{!v-ddFt5=Vbbqf`>$_&3NVzsrgNfPt;xJf%3jZz|XCnwuiLo!?O zRzig@Yg~6j7kZZk2A8FkFMl8X{s*Q}kgzuB{c6Tr_m8H$NO8^P%-3-jPtyhkP!k_s zaWv;W%i70UZ?cQxhY*pfX4N z`ZvUZfDfs2BB|8TwCa9whUZTCzax_VPlfjQaj7|MS=5>UB71r)J|99IU91;lDg4Nd zg?=`oI0{j0m%>iN&Ui}3lztxg{7Ec6g^M1q<(rtGm>)ci$qS?qRBbPh);8e)~guld17$ zpW(@5hq97weeP)k04QRys829^^cok9aS0T5!EI4puoj_bSk=D$2d16F%!BRQS&=Jh zr4E=T6^BEKd{~A#Zyv9shQ1cZSHw;?u1(om(vUI7?xeGDHs(0sVQewc?`!zazJy!7 z)1WMqE}i=|AV7|2xKcuM(u{d6t3dYsiRC|bYR@|UWTq^&q7UlUpZzV$&cMUCO%d4O zx8HY)WLSJSf6+w#o4pOEBmEgCKwaZ|>%sQ1;!@oiX?coRpwl4v&|m3c$kWD z4B2y1ZHk~Wwoi$=?3^&i%h*&^?fThw^Ye?zqZCQO6u)Ta2P-RV0oVjYK&4^{GUugzlS=Dsz{!TT4Gmm5DQHRQvyGlSuwr$tJUfsn?-{Y10zN_ zc1c%nl}~sCG?=t9Iwpp^!~*P`A{g_!w|B#|xLEqbgG16lDX+XvcZeKiMy^Zm#(CWF z4%=F@NpaUo7Mdy*xr`c3M;grN9grj$4`r-2ZCK_GNcqq?yV(rq_QACm?e)>q=B6^Wi|?AX&T;wKO1ib`PmWU!$5nB(Hqj6(AJvpk zFdc{mz)MxPCPz-B>Eg7JbY>ZHbKw!+oRh$r{YiLmW2^sxUy^E7)Va8&kW>M+Q!*Nk z&PzEBha%GZBC~8}MW~B;pj9^1%M8bWx!+J}jC2 zO2kbMz{VAxzz9lnA-Jc|m0KWyK{TM7-bP#)V;IoEj7p;;_y;Br4B??LmbZ- zNr?PblCkZpNGwQS2To7*Zo94Dq$}^V5Edsz4gBuKh#S}%Mo@5!A}n`d-@x6T%xx`n3&)81{3$TfI(M^QwZi%Gh8`oa~uZTbU7FX8Z#bXuiBTa zXun!z)q0^=jG%6gq9Ajd`S#JSeuo^sBdH*uI}$Ee?t3p5*R`Ap-Y({kXOCw-%fkFAEmcUuVo zAzZ?lL`+$L>>pqThoTFi|LHFJ|M)iimnHWvOYUEm+~qt}CjKzKI8127_Xv_nG(qM~0U5SU(o=}g zAix-{*&2Z)wOJ7rsRsR7;Bmd|<9dp64#=!a?-i>BO^*BTgvR@9zqSSKoQ2Z?;xKhP z(a+>$2AN~Vjt%B0)6MqyLj8R(D>hg2M>v4qRQt$H6wc@_`M4l18x~0R>)65xxnhGr z#!faeV~aSk8VoN{Yko-A=d7@WQiX-Q;S;Ok+GgfS6)mSIeLN|?(~l}td3_331=4f} zK^Z+ih-Yt=Op`b}MsiKLLUi5sH}+y~-tjOF#J-ZmGqt)L>vA}pQi844Ef?pshejDmv zXwb*%GJwAy^w-o?IGqXNKJOAVwV&bDDx8Q0(u9*FNar}E)D9IWv~Y1|gQjN8E&R1| zRt%)$;ws4og{M04sWG9!R;O-%oR`~!8!PJ7%$S9S`TD*WqweCVD;fvpYsm9FtX?@c zEXMPUwy$1Qy^pM_?!P+=H#YySzeicb&QGS9_yBYI+1d9|4{yl}VlAHW5|tq}+S;K4 zp(`|i@kCp~sHh{8y-lZ%kL^7+wdW5{%5wh?-@N}dr^IWN;3tDktQQ{^tZ}N>q-mzG zpx34mBmT*hfHyly3nnD1tEKMc@1JNU$JSg}65>$Iw&A#z8gDjl{U86p*v#y!A0AEz z6WEM;XD0}|w5a^pi@wi#u~(?SkXb=@cMOEeP;rtfzhqPHs_e5&$|zp(2^j1cbz{-7 zk@{?Ze>TK_*zS7hjjKsp8jU&a&AGwFT@m3;cD!W~N>Ia1r9+?dWD?(WoDw6{h2ndo80i3LT*K#y!8yBc? z&}aZ}eMH${F!ccgvgQ7O1ekLHWMy^OtX>kj5C44zKZxU#qy*<-o)RmMCLX{3R0Rud zD5@Rw^|HQwHsE$UmiLUM$1b?^7I0t%C!8&g;ld5*0Eox=O(=oh%La=&otf2m0|$#b z(hEv>T4}LwQNz=7kMUOhiPJ6=NgD`_w@<2k=pI`}Ww}VaD>%kd?-9eu`112gcGJ|i z0*tbi`CTkJddp6#%@1QPpH8jM!BCz+J=HA>BoaJzN0>%U(7`1FmB1zopSwhG}TE1?BR zs#I`~ejU4r&ZQd6b>C>l#{ySY%7*Q&Gtu4~PfyEFi(PLtTW+QZTLOEEczct|o4ZTE z&j0e3rZwB1Z2V~K++)V4H#Yhh4wkEt`6=8Drq?9RX?jf((F2@Wv`>GO>{U;Nk81;> zc+O6GPRD_m3Y${7%mJ|6-AQB5GB+*~51#J|PZ;fDqnYoEATG>2i!n4)&oKK$F=r)WCCXDNl1{H>oDmsIQ!9BiM z22FM~;nG>f6F6I@NrtQu!hfy@w7YT*Ye^Wbz7vkd<+Es@q=5-lrTvB`kCGp_PMk1b zN6h@dz@aYd*;t(8(0bS{y-^@-Gh$}GewH)=P8C^1&gBjzC{p0Gm0^3}LUC|)> zc;Qv_po=M|6ltbo5ILHS=*9aNed%q!-*DAL>?pD#T0}oMRl`Ex&iB*b9wVqI2-Mm@Uu@Gg>7P#6SYWP^g>?P#c(7Cg;)CQ zfWLP82a)mPHC&nwx0LJfWYvvx~&tW~VWO)}SnIm#U(rWADKp|DMc zORq1(@iJ;wrIgvQ>lGdBIT?jL0eST|qgo1%b4(Ak_zrFR#YJPHi?P-87|~O8@l<*$ zJee9!>TJR7y4(cEex4m0QKgh0O55)?BlBs4>fmqb54WXG^;lg_$8kdDTMumy!gcT)Szp3)AaRk~4qJEmJw@5&q#_M~|WI+Pse_`(}f8u(;_f5RGyA&PV2B)~&;4m<_4l=k?pn|)*71zPtwYU^# z(Be)DMM|OV_SI&0lihEAFE-h1KIhewoIl{?Jook7*Ms$f;pvBSYJopfWW9N~41WyM z#xEf}Y3=M|wzuL;v7Ya?-`?yzAZgBwDG))*CQmuUi$$W>xwg64Ysrs$4&T%;?dW#) z2I55mh)4D$CZ^7UPq-sRAL}ei1XPIlUCFqMDgraUY5BTZd41=flz9>ntlQL_kI4k1em3N~e@zUjZjLepi)^&a{|5@}!uqAp=uQ5rI>KH$@*_9jZ$kJ!`_HmyG3rE^E!!sO1X3wgFJ`Y z)uoC?Z_nKw7CD+ybo#wKBhE>oG4e55KtT!Tktp#`aZB2U)hgFxsWO4t)NnSOR&5fGrbocm(8pLv}Y@tkuj^j8!lW{aBw{sVM;UM2IO$(poC2P#(ep3 z6H9i`6P;BhKJz+j{aB=*yi4OP??)#veX>TlJiUqtp-4hYxwXODTYOvB)P!U`X?t_3 znhRx9{_Wav5e4-HNU5ys30KN>u=95SuMc`?195V6;R}BeCV+UmxYks{{hEcVM!=o1 zy(WgvASk4W4(xxl)tVA@y)i%AKOM z=7;ko?%!_Mjde)OugTVl?UjF&m+^Jr7#ax>d)*2ob!^_g<}Hmd*c5l>sZm7z`RHHp z^OtWHR=L4)m6Wc)U66(F zm3>a`Wq%E|Jl6NJ&;JrOm+L4xws}RO%k}OrlIm)bpA;`7ctMYmAqG`iC_<*f)!O=53c{Mv6@SI-5oSj8@s)tb7khz5 z)C%5E;Y6@uFKGD7bLYZC$|99(Be z>cRnQE}W5mhNQsmgdhum_b}}uwm2wwHKfXbsHt;N%A0IF z3_%%<4DU?|%P6-I{OC+3L85cju0LFL?1Py_jrZXpZpMV(cy>J}0e5ZrK7mM$FI0+o z+)9%!3xG0_`T2-lR)=H@)iN%7@5fpmOYg%>zqa#RQI;O_jy2je^bQJwybLG(%9{&0 zk|k|uSytjKOM=a$>F3q5d-VX_%8kj4TPTMP)KM>}V#`o}_Xfd$^8>oZAv@pUjOE-$q#Z_jJupeRyYo}kHcpXI?pVe=pSViG zIm>c?ZKl*)nQ4n}cn*QAd=r#r`?C!>vbCKzSDs1%o!PF!36jNl&{eLi%Q;|~M`&4n z#C{|8m=5+TBC$NP)Q~(`CaJ}gA%e%X%K+P2(W?`zR}wQd3C6ylA$a?50c5Llwxtv z_CwU9T-p1HA`VukDPP{gFWD<8MRAlRzQ-AF`C@|sKJ+p~!+7INvm%pV>v@0)6(y*| z{Ibr7 zozo|PwlV$J-?zu0&X)gn%Qk{Qn;|7%WL{b!cYLmPa1M84yveWSFm=v*Csc;9&S5g$ zfca3tKL;^3_S!m)yAw+kE?RPKOvr8vuBC$x^AzI3zGyCh> znq1LV*XDKUuuqkI{ixWgKC=BJ9)R*t*pffBh$_6tj{gSK0a@UM~y#%H}rnn`9jryYzJE|-tFq6 zDa)edLdZSVsdzTQo)hfyd?zR8Qzbh6*!UU+_Wl{c`N0|yIzCH&mrc!aEF1q~yRBPnkQHbZ~N|np}xbjG@VP|B_1qP&@>avA8z212QRA zU^}G!JH1*{oMHJYyA8k%2p=9~_(<%M%+~VI{Z8ubWBIm;k!Pj6a8dpJp7@gqG`eE) z;#ndujq_+Sy#8%%5Olk(bAzv>g@SQG&&zqLhT@|kDfJZAbzFJ>zJ(3772mKGU|6foYAD#Wck+K{#GG6E-$*2*kdbDaLaN*rS)tFQQ?? zZyclArCznu-7>4CJYvP9CKzWQ{cbJ4Fe`bt!w=9_V186(;$t|?gm zLfaIl#C~FyQXbK&#ZI|5{>6qRGO;9s(ZQzX=~Bp4xGh%Bu)}$yKYxHOevG#})u=aQ zg+|v_Al;nX55!w}NQ$E#=7ocQtv;NUoHO}mWl%$T+{tf+n@O-KeZn8VT^WUM5Tw90 zWILP}S)9e*ij{%6NP(xdt+isid!Rs1(l8#bGeG@bQIjh;q%om1xiS02lyNz1a|;JtMSuLG~rZg_zvG~@#* zxl+Q)3$v=S@50ImSQd*a3}T#Wqh^T~ei%FkXNp?d`Ca53n%%04e=#U_o_qqVeV75I z33?WoB;r^_b`zzP~Asicm#(yyIVk58B)HBp7w)|GaYgFJ1jFUHvaz{V!ep|53W?KBL{P5;w0=LcM4d zF7=vJ(=}qw4~y+5m?966vA~tCv~klskm7UvKoUj7ijfy>5b8tCZao?fU3X`x!7p74 zBsGiJj}y$Wx%mgrjDJ4LNFy6@&LhULN}dcostrJ(8?&^-aH#(A?{uJ^q%I@gd@|pH z-dgp}+y!FA)HVZN1}$t9V~|Ge6!o52de?%FCIl4+<+Y)p zsI6(+Pen!5z9=p(G$b`P7LWqvY&h1;7S6H9H?m#jTQ>x6oa?eKneZAQJ6DVIQF``6 zhp?*lhJu}e7Uv?Mb!3mhHGRgPQ5KZ)RS-zrN!P70X&B=sJ|)6aOq&VAlFdUp@MJ(~ z1LH>8DZ7-g+L-n0lJF(}0s6b;>s|Qx@=$7_D`WVCr>EBq7&OzRRm_xPWAgi={jhZ{ zdmSH#l~67$$XaS(lRYw{EcsHm;GfWT91tpi*C?O4-we>&KuFSn^=$Z0kGbTF}6+)m&ore2eD?^@aJaR@8?7Q zIlUg*m=JoO0q37M21;|b@xtB`a)~dq9ozX=#@-((^zgF;PqD|)!gN`me}tcE*0QJ@ z$4G~IGo$iSW{$`87m%kc%-zneq$vd48NZnt&^o=UtmU>lUD3o@HNhFRL(A<^0+Q{Q zq}iJa9rnR>J6o8cGqTKkk&--;767@|Na(&U{-Hyu9LN5Tb=HrvwCo#H*4Z5 zi1Bk`X;&+48wuE^t-Bv^Z&-SP7mBpEKvuj#H{&XQk^1ymu!w*>p^@tCdo=04hmvEW zH`G~~>ua1g4Zppn=h9}sLFna(V6zyY9Fb&g**&AE$&N%b#iW>Gzd;7crO!`_zTU;1 zu^)7+85-Pn-1!mcOf1!P>S}DLdq;Gj%&h5*XutZiXUrU?@#DMkDTHkvzIj7|}o+=ig(be!ih(PQy_E-ZU3Xz0?xEs7*;qvhOQI znzyE()PS$;16s2t8car(TD5(Jx4s-=TjQhsMe4#382HzqqLeCqiuHPzT|D6{RAO?6 z%_;Hx@%KTmCdVx~GYKpOwNB0lwYyAfzvk5DbzO|nC%~x)x&0cMu_Sz7KRWUBl@tvJ zxrU%O?&t;Q+<+(f_FY9y{T}s(=m2}EWiCO#CW#3UQ=mEU(C^Fm3ki9)qFco#41&@r&+#URpA!ZXk@uf z;{M^(B0E&;+i5P%rw0+9#u0hu`k?E00zViZghmRL6{IctnW!l;vB@ zEy7q=;v>nS@#@8*@a1BaZ+6!PwbqV!v!fJ9nuH8MfjKWTiiq&gv zZ5jK($p$%|Pomt^Qt7yy z9yF4guSh-EdwK=45?9WrfNu-W-1AQ?PbA2VC~QewYP#j(4nx}O?NYyEP?uNPjVh3_ zwh)OWR4A5~jgA`X_gP#Dw#ayblC9>p2KO0?KsHciRZL2t1PDI(uwJTvQtK=De{Gxi zPYL;-67oMKe($>w$<)8VfOcGGd^NC`lg`R8JQEVnq4;t;y`iV zp5g28Z_OEeCqm~$pR&O4L%WJGL1h*Fg;dn%j_4OwefL!P0Sa*Z*JiQ&MTI@fqPqgX z^Vw{zU-EMfnLFaAb{lqZuTE%C(PRmg&jn zY(KLpQyG|f+VtAzmqAsxT9-uPleauFt+^mgT)xqxB#G>sEUIM`MgB9xp&2WgiFL?~5=uF~-+Rt{cbs4+xtqtej*d21f3mc0-NjyegJp8RWX`hxwH%mUN}~}H zQORi^ugFJWDh8q6CuoduM2s7am{tNYj`d8ON?ey+HYSIj*VLT86vPtuX zIl3s_Iewn2#D;HcXs`NSQOt}CAM3A0f%U(Lco9nA=vuB$e=eB>&*(T#^XU6$;q&i= za79<&e5lMYIFtQiW>&RKo>!|Kqc`R+h<<+nmVzjr3pVA|<(dXDZ^On!4_0i_pXI;1*glab3VYP#4g!8YQ=wOjC5y>zuU&S|!1sye}debWS5^Sx+x7k$&uTX3^8)8?mNwC^w~iH>4Yxoj?_YT>fKu;V&; zsIVnRUDuQNjK9C~L&oE=X;o}>hwk(LB9R63h#Q)8{mR*Tr};!1b_G?Ezx;IIV$qzE z8fc*;R{h@7T4kyRL_Cm$ADP5 zqEU>YTFqBZ65$KtI^BjO$C4EAPkRdT7hhjpjWhDvx|um^=Yyb~;c~-#o~8;a(2t)M*PXg5w|y;x!b@I0t3f|=CbN$DOHasCylvtpXEdcw^y zQ5A_cx*k8ynX})ZkjY0hha!_R)dV-tm-WQJEsa9esiklKhscZHR+I)Ng$rH2$6^IbNSG}HcGUj6t%{K%{Jn(8iMJ@t;wQF1?5f-!r$#Rj2W7q9 zS>?rBlvP8a78SBDPO%tdhw|& zseQF|ARlW-EPSJg%!KOU(2`$aniV#ep}EbhO!BWBy0XFIJJ;Fz0j18$wgmg$-Dh70 z_B-I)jN!KytnF_KBC`C9%rD?#apV^~;LQN(kO*`p-);%I=K7{`otGL=Q1n_R-_aI9*$+acU*+m0^;(AD?`#boinM zw%X8L5PqdCTC1`b-|MpC8jkJ8^{kP;T;{tL@9^!;VbzdddBXY*SU>qWl)S#v4?bhC z$WIgCueB;9D;8(6Z#L?80_z?5*D%HieGRf(uZ*L8Kh5j*3+VUWRHW7e0sMMA)IZ2p zfapjCYv{;Vc^qS8+a22804XhV5Lf1y&rh)xaDIWA8OV&^M9Ok#9ETwHTay(bT2D|m)&$ecdYL^;qtZXdu7BYr9Adoo%W@3S|GyL6 z{-?G5Piy<1*7kozYa92Lptj5j2MMK)_}DG<%r@<7Eyk!iaoqbkAcUHr&VKM~G$7j2 zM@2zLciOGDJb^Y1+@wC)WBO#|n!02TEGWV&SKRh3Sc)5G?crW$KWxLx>Db(&*lP4f zRUb;{z|AI%PE@ub5rE->HOgzFAkAueC+SqlXjEAol&VNWxS*zDiF8+Dem&`4f0&nd zaiTA0_UW5+tO1juIBoB6x-vguqns_(oEEx3WJ)yRKmd}Ss^Z1N#Ij$44GOI!EkJw{U5BP6KC{WwmQ_Zq0C2>cG!C-ED-% zPiHEE#LnX{IIU~$Nyu9hMiV1FqgKy~!3s`9S1wxVhxAYuV8AoH-VbM^ZZPm#MS3uY zZaO}F26N^ckfg&Z3u45%(&V?(SkXz7dCKzC)xuL+)FfIwRX{ty5991{Av%gI$(D9+ znQ5pkD15J-&-HU4?Oz*ogaKX0er>%C0Wb+CX7`IhK*ceGY5NQ0CRL7~&~`V4lEZA; zwl3!9LTaXOJS4fp{We*+J}Bs_*UNFnYj2Tl(J$tu_1c0>$8AwiyRi%A@k_+>!{>FQ zN;!i~yrt3R7Mvty0u%l2EGTb(e(ERZT2g8a&V}K55(J&lRPKqH0u835uURLh7V8f& za4<;Sg_hf#A<})Qe1qSeEJfQT{9#{LFqd$DVgR2(KNDVJo6`E2-k3^kYxKN|B5R|l zfJ%%`0%Vr(Yb+3-4PO%ea=I(8dx%EV|spjmW; zp#)$t?TKHQ!f8tIInaDi>)t$*Jlitw(6PxDtqsGgO<}kBEJM-@!b+6oe7Xxt)g`1C zspLpXE%XdJ``Hwf{letJOV#UCNr=GQdDlzSTAHy=4@DebvXe5=^g!6o#gRa~+R&#hgPPsMw>fju2&ushi*H1}0K?$O) z9_@{eqRCSb9e{}P_6GwKUMJ2PAVosWO+C^YMFT1Z_5>Z|y~jy`F}b1rMEyh9elq<$I2IoXe*En0fXR1@ zjWgfI=ex*E%waLDCL6CI*1+o7E$n(>5p+%D!-Po=lU9*gvFWfYow#|EcTqX>OuMFF^oy3Uy>Nece>mG!&A83pc zD3oL)G2WcO2EJeVsou=w7e;-br%?L=X==Lb3r01sanf2HT&JNw)o6gnGGSR=zsqfh zixL+QeHknU&xR3Ni~0+vuLLUISrT(fsIWW6`AzdN)U8=?blzzlPPZXCiw(yQ3`Y)t z_poGED8XI<>_aGfPI^zDB#re2p2yg1ZB-Xk1i-tjb#2=rL5?DH%ySB3K|iRIl3$PE{a8KuW(ZMk@~^>+o(s+)-2^c3H=b6xcKUxZK@aa1Re zErkg0v$Db8!k7?SyPheG1r=`64GDDX=RcTfRzL8U zanmdTM$aTB?FR_Nq9S^N&S9c<8?)v20_<3U;@aEG@7a8u60rUC2*5yEH^_VQ`l2$cDd2cr==8I%WfGza^Pm-c)j^X!3hnfX zJAsR{Ym}z+>OErHB7QgH+vA8O^#1K!cg6%BYJtM+dAh(P3^g_xs=M)dikRJ(u0vZwFnP zk`k^kM^nHFgZ=@dpbBwe+ee1Cjm*pAp4q$+!KJLPsN8G_&kEAdawwzqWo%jPhM7p_D2S69L`v}5e6{H|>tQvb^+9cN zPz8$%xm+fmyVkgEHO?7MXx0V1HjD}#LsNfcx6-&MqP|AhFL@N%DC3$0_MRKNPf*ry zUn5(2bc<9h2=@+2eoIQXK%DH=qk~pY6D;$Hk+mcohV(O?TO7DKvomK9E(~+pBFD%&7IK2_5V0lE(bfF*(Oh z#xoC3z$Ei&IqV@URkh!rFNVA5EI(K=w7aPO%0PQ1gJ-FGBQ%R`f7=$^F_~mz-0gQg zsKEpkZ}Zt|jlRv4h`vId81v2b=NK6q&K0>>r18ojjw17ZGsuHJqc}mj*}&x8sM_U? zF7-nil~QfckUV@`^!Fg=F-+eHrbZIa;=Y^3Xr%8B3cax_-G8F||k zgw~`-%eAhDG;P5v`H=>88PR&}n?o@s*^tzd9(xnC@(Z;JOBPu4(PvriQ?IO?$>!ZyROl}D!$Z7vyx?aaEkGY8h2)O#LG4j7F;H5@YGd>_Q|}LwtkmV;A?4X~#(7&RKTB zuRo#Y%mIJ?PN znXF8bf8cIXB_!u;QO0sfp3!#WD=}G);wbr6d&GzP1HkK28OT}tZ{P2C+~uo6&iB8q z4~wqQ_scVJEiWVWS~v0W{x|{k_$^a#fq?yiZ}vz zqOODN^nsRgGMh1H2b-*Q9O3a7DSY%Bs&t;#=6U^B$Tu}cI~`eIFG$5WZHMjpA6JzA zuBirK9qSje`W`HrdRY5G5-L;sRKK3{iN7syUzrpn(Aul4HD&fDG3Ek?)6kcifZxdH zOIVBw7keVfLc3?PNqO5l?QyQXO}!o)S9M%l`*e2!V&Gc4bj$s}oDTl$JZaBBH0~MWw86%Q(xUM!`qq^xV zCdLi~9eJnnZ9VUDq=KZn(`s;IP5w_P0EPLCtAZQaOxJahD2NB^JZtYY(dB`OC3??# znW(jR;?jnf8YTD*S2@`0D$rD|we1^8GR`uTrjO4$Y(&WA_T*SH_S%pEibTMivrJ+I zQ@>A^IkHt7u~a8aa1(+LeVgR(gD~q}G2rIjMK-4Kc#3O8e-6jRcD>}BtdVFgk&sD% z-Q@h+fPeU6D|pvsB-PUP)9;f1G{%M*__{3a(|-42JeD&Kfw9W!(Z^T(s~Y|ONg9xG zm1G=(p>(z8QM1fhViN_Im!Iah&_MLVSowA%nYYa=kJ4%mFpCCeFO9a%5YI_|Q%{el zE^x-1_pe)tq=X)v)dDUTRadz)dd;1+4Jsq3L*O}K7PVHN@w`-Ea3wX;zj=Qw*2h{m_lzp=XEQB%nL$h<>M|db_c*JvCP_ z%rjL$P{I2fMe4y5PbAFFM@^IWGe=0cbXSIC{yu4He`hV_l$M=<=-TCVG-UlL^D8u%~F73n`dYJ83dQkX_kwt*@(QXw_i-KC*LR#cD|4 zw-qA3xSlGln@AR!kOtj2!nE7pi9xO;FENk)qU6ISLc)ex;Q55ZuGdW;8lU1Su!I@Q zDapns)B0cg-H+7S95yy{69xDE&cp1oWhxszIBy?wsS#%4V`1Z^U?uNP%x=((%UgwM za5NeS&(P-XSy2%*^sdQJse)0)YG3EZSB-TvV;PRGN1#7tTDGQ`9ys>kwfY%M<8|75 zy%RbknfYBYl0Gh;r}IwBra?IE2k0-7OrDBG=J>v)cX4%3fAA2elGfk27#T;&!T{VX&u+ztp+VZ8U zA4;$Gp>pDv;e+JH>IIs4w2yc~0G48n6I87t^tQ)FSqTCgwvzhndMci0K|1)Gv&n|r**dghBCrQq1{~-CULP`))ld0-wvgJs|CBu+J z_rtAce}gH40+zXHPcZ2R>*2S~My_;b9pfM8GG~;!K|tkZ&EcWeL3U>ec8?shA)7wV ze>gcB2Cf=hILs>ci!STC&q&x(dM3_q{cwtj&V?8Zl01La@*K|nSy{q~fp@>yy+5N1 z>Co~>rGNigV7LlTDO!HPbT}jGYv)JgmYrclqXykRQ;&;I`x9@xNGGN9@fe|zdF^eQ ztBZ)Sx3{4is-@&6Be-h?#c2jK`>|dpC3}a_v>sDovkq`4rT#x3u>2n&yA?0-GfG(} z8xeeDjdGjMnjg8;Y_`=okZyvFSD|t`C>S=^iyaq_w=Ct&t1f6R&X^**!~%um^! zpx>WF6I8OY1dt$~sQ%eyuKE`wf@0YgZO^JXdzxsBc_y2FAt=KKJw?y$!XhN%8#t)= zI@kALAzt6b(pxSB8sgPQsQ-FSGg8b)KN%Rb@&t+oF5WY? z_NWXmE+uETUFmkOh+J*N`#jl=h+lT*>0er_8kv-pNVqi{D*@V)1@V$qeqXZ5oKg$&MGJ3#1kk88NT%1V4;m< zdh$0efONJUc=O?@n1G7SZ|&U&;*ZmQ+-p_!_Z28<6Dld`nAi45z}^|`z|>aB!@{zymAilLHb)Rrnty0?Bzgv^^~Y=ts4tyH+@UM?T2+Z zkHypLGLmzfH(#jmlTV`a?Bv5U`m3X-7l;16#Li4^l|z`a?*9_XPToqE@A7_=^N|}P z{#6;p^cZN>J>0l+_u`kX{+oRze}r%M{Rf0CJRBLZj++c_+YYNjlmYBXXk%EptN%H-PT)#@|iBrMJ^{Rk(GE_gqKKZzpmKdRM0Lx zOQ1~%)nX_*+dwFr{k3FIo$V3dRUMAgWm?*YL}D57OMo7a znT|hMYhC7&QO_70IE`oJrAW4I0>TpJOXiHgbB`MGK+~xt(NVCoa$s8sU9|O0c`>cl z9585keF`JZY)teY*lnph6hjY%F|2LEz!P;8X!_efcyc+h0@Xbd3{$U`6|CVPya>t}XB z*T_))=us+pMl5r^OQlZ8E4^va2GgwWh3MQ9oJL-c=Fa?vDbBoIQl=2Apf%$ zhuSM(Fg{1K6sCkmXXkj8u=!#9MH;z2-xr%ofA^Al=>|?JiNi9(z%l3RCNFc+OU)LX zNu-M{ygOW8b^j`BTCUdMQCZ?7RDY&!rjS zTY9_9jqcb3#CIV+3XX+FM49HEapKWM8_YDl-bKL(ALfe9E+0>{6}%m{h4$-8+cbo^ z*Zsg&j0jguZTFxF)!Pg`CsOQG|LY!lvmI{<9&c#dU~0iJG+_Z*1nh`!QYDex)zE~K zdR$`*7t#g0(ZgJy^T5&m9RXL#%}@%-Hsbl<6fiNi#)NmdhR?%SLaSvC*J2khl31p( zdRTxBJ6b$r>V|5?59GX#m`|v+@YP0Pcwp}zI2r6-VE9(oQR>R-56aww8AKbcL;iSE z_F3Wv(iYkl$3x9kJ!$Jw-(-|6h%Q`T=W6(UC2Zh^C^7mS_!dyzfQG|FpZv=j?UA^e zeeTHA(2mZ@u42_?J-jvye1vU z7p&5z(J8@VbRW-c z4{GjWBuG5th=$B4H@K45ynLP+W@K1AW@$D-bf7p2psftBCuB47>yO#sRCE=)H6MAW zk`xmbW}W;Xp6YGK{3it_?}C+}P+y)FWq33dwNx3Wih9W_l_~S2$Jo*^r1>WvE+J~v zuKT-|h&bT4WF+rCOrIJvlL0+vT>)j6l<;v+0qhIWeB7B>*-Z(gNyVN}<7afe7j>S{ zo-*7A%39xXkMQY~a)`Mcb$9b_kNDoL7#PXfwIhU6AW}{3J+S*@(nZa-y;F?O?bC+2Jimg zW61xz;XiBHf7Y`9tY!b7v6k7t(Th9hYE|VSp7Y+LdFgZWG~3rdHk94-ChI&AESRqm9KxL2 zrutSj{9K(MOe(9}K3N3apZu8!3NW^iFJ7-t>HL6M&#QbYc>PhbsSY#m*5gwl`cswL zAk|+a!p15MW$dGQqmxGx9<2O=7Kn;IrQJT;lZF!j`V?|!S?79xuFkHjot9y+Mk&}t zm5V^g_n>fMH^)&GZq*6eX&PE(;BXP<-f(cr#ZjknhIF@bwVJKA8NL&45|3E-6qs#O zQUV}tLPe}o{ovh`xM9`vzl$DHj6}b?X6jEb%T8u-uJp#~>fecN=fRTI*Avv==*M&G zbGT)DGLM(s_AcQVww*we>}*TEy71VVOTWAFr?%nJp4;X-!mhmKfzR4#xE~7Okr25* zQ&*SA-eM}OcwwkrW!f>4iq;w!GI3%M*}X@M2|m3O_Q!_Kk39;I9~~DO?OdQ4?lBbJ zA+ercu0yr`J1-y3UoQ&BTe{!x&5hG{;0KXFG?<2Z4Ifzso81MJH@;?!cUAHNMdL4$ zPq$hpvA>Bfv8e1faRXN#P3nNJv2i-&t*v1xo)js$6PJ33$Egn4<_@i4yZt5*G z!(_4tlc@B1S0xo-?Q*pcQ0Jr)^yc`Ax-a#`u|sW-jfSUSY02tV@`w9+L(XTgnH?;U z4n99FGPV5t>JWd1g~p0>n8eq*QfqcTcEqe9x%fgo)2CmkTyLTn(S%$oHg&h&ZH;4Y zFQ3n=EXB=4x>P^Smmi{M7rQcwTU0g|97O*YX`O%*Z|m`&&3pk&ZH~-}=I{P0snD{0 zNQEDg7rC}9XZ=|k-NdVYmCb!Mg{cInq=kOxWR~FucZn0>5+4n-yzmX)0=Grc6E}~u zA+2@U`fxRme1Yd_&87>aLW2tO9(a^sU-r!EH?V)d6?R;24+L^Jl9^>hFg{iv$Z6H$ z{~YrF3LMRhSbfB3fiD4!{wd_iLPOy!nHG&tsBtxJ^ry&E%hLI!H^$wEiyHbd?(2CX zdzpRJg~e2~C!TKBWa;%4;`x=I?l*+$ZD>BVu*T<43gH}U+ucy!BI9--{ydAOH0AVG zSMnhn3QtcIVYe808H-On)vq23l=C`E2oD}o+0fP$Ok6h4)U?z1yIMX4hNm0P9qA3^ zf{9fPw#;vvT&F=n<>W<7q}5l$YGp(A>2)w4U!7osJ3Mt_A(_`ShEwbLPp`BU7s;Qp zCSOeey7?SO7PD5kTn=CBXVshBo!9OUZN3#rPg*!gjv>j%lvrS)0;XAI>h6X+)bkFW z*lWH?>CV$Pi#vk$j;6SJg}IYIk1wVYwXjP260-)(k^%krH@=cqG0N+?Sts&%)<$#Wf` z;(ChQT#xsG877ud_GgZ~xS|`-4oyI-(*i9)`|WXhcxouw=O=~k>x~_c+6T#7MR(Yv zG}HUKAxzh;#V-0?Z(NMLq-sp*)nbDi-6GfZkZ_%2p_OoE4BO#@+U~FHj30v4Chb3w za?Tigy&>y7v`-GCCw2>=$4=uGQHEOAI*GF^jYM&*A zFQ8+6$w^Koz37e|a5Do|A(K8)e^rz3Tpgi47~8)y8ogqVSRjp^oL_b#ko2k(V_^|Z znTbjFUaRu#e{eVzI{k+^|A#sMhdKYRV9tBpsFnI;im{5Lpis@*wniOp0ZV{T9_z|GPitv~pKPVt%4L-~yw>i^c?h8Fkexd9PB0XYrf zfZ94Iyb`lY$}-v}BEe~0_4APo|KlF+2WHBgG@=+{2Bz$<_9P_0czW*}poDi+n0d@J z3lA5miWx$y=ofx@rn^N4pKmFV@EnDe*&d^i+D>&1a8qVF#G?)`|14q8OUIh|)p!7Z_Nnf`=b%RwPVdh0eif@7 zvUh;fU#F1^lJ(5o-3R2}L~^alq5&tePtB()njK!J`&czJz1yX(+gjsn&D}>A@4JXy zj7W@pKeP(mbCxZ#ld*i;_LJ`FJ@zv>o`rn`NX*RAl%Tl4ztFbn_%nK2+E4&y4aSWf zOW<45tDBD^b%fvCZZ;Y1W_Sag0fkRYa2C?6MK_Lk)ckOmamT#=BvxYk;0^!Bl(A z#GA!QO*o8-{VM}&`#RiYzQ(R8Cyj=N=nq6Cq8`>8;tlD?FH2m^bmGPq#n%?r;_ERS;Z1Rj! zeDlYEj6fGcyi9%`uQf$9VZ?$Q=bo*cgH98R+hKT|YP=~2@tBAl>o>Z|$`*sP?GWz@ zCVj{uC+lzItS^nqoHhr!8yafsKuF@g9oee87*!7G$96yD)EIxXrU&fupXsLP{;E`$ zK=4K49+oSA-$vC5aNLhq^fB=-Qd{|o*?{u!1krW@qx{my0;?-52XdkQwE=c&JdJgF z;q@TvMI2G4iwmLZAqhw?(RJpiJz~ySn5(v@YugoD;eT9(CxzstPSm3=f8um0ZcIt6 zyOIWQ@1YMhaq%Rw3a4@zGkV6($#){R2h2@lTy2VI?F>P02ICy14&vu(A!~0bqs*&x zZ+gkr#e;}S+)o_tVkbNS$i+k{<%5&CcMe|#xc;JmI7>AY}l znA(B9jZEt(-nYbyg#^x&DSntfNp0>-vh6L!{LEqoi)Tp`-Mrd=e3L5%%ONr^mmx{$ za_ezbj4sp4n&Ofg4rS0~^r;7aRq2+mOSKy;ZsxDfhy$7H>qaV-vSMWy?(ucDg`tUr zGKhPLr4vwPRWLbp(w0~K={|h2b)IX9JG%}{ZMrV{xrv|GaBy9N*lTM=7Nlba;(J44 zMFDy~-=)D!jGGmUo|@au<}HR93!1IkA#G>h-Ci!T`={TtCFR7aeKp@$;}0t9!r;O+#M;NCcmJ2dXD!9zo1jk`NE?h@SHJqa2#!8OV7 ze;K)V?#$e`J8R|btg454s9JTtv-keKpNCsOaIpRF^Q&(rS2Z^CC7H4=Tsg&EUV6~a z{=jKVZOX*ufn*`;A`x!4xNAsJ`64`J*kIk5*?=o16~X$BxKJ{cwFTy1xDlB#uEc0& zXgCSQquf+CGP-w8LN`+VBl=H(dT2pcv{x;n{s_HHp2)BWNp(43`|`b3CQZM zp`n1DNPRweZ*6&-%i3UG&MGf1Qgl#oI?GY(|FA%j#$0CETY?QbLa>d{ued)(A1wVl z!=NmkE<5&IrNsy6JKP1es7Qa_7IPXJbam)2w##;C72XVgEs*b>p)Q+qj0ZE9u9b4u ze_rJ&PtK8o>Mm#zvaGugUd2d_wgTN&vd}W5*;j~kYYFN&<_t2c1I!u@fvhrkzdmuJ z8{5=65)MESupCpeQk`on>vf0;wj|iKmNsVV#GbDI!dZ!RvvE?ZpXn-WNg(JF(Rz~H zOXTUTL;xNI)n?&emITbu|H4JnW}iYp;JZg?-H&CsU6-Y3qL z)~8!~e5Ug8i7E#O$r@zZ@vP7|lmJm*7BcG$%xq++s#l6kjRyFpq*4vXDH4cp8xU-8 zI2crYAzjNEI1|hSZ4?zjL!6q(xW+|*##T|1OGkg^0u-vVANVJk4^F78CR6QqWGgD4 z$epKK#^@d8N-3B}2$@sbR0Nau=KW0UBC9s8o8%k0=Uw>;8({e#y}RPL3CfS0)2|}6 z9tl@K4fJhSBuL=sw%>8u3&Va0)F&Np>Fy?Zuw%%Ut5}i<-Xb@CJli9A`9j(i$!oJ0 zkcsAgt;YJ(D~#n=qMAP(o|m^HFJsr1cYqg`9q9;X+taTj%Y@C(Vljd!BP9aAH<|q! z>L0fTwwpIK3AQjAG(9k+`m(qf~UPrZM9O{?%05rH>ti_w7 zOP><-e}&qq;xWbq>2A@Dh%{d+F9v$%zj?(K6so7@i!?#Ek7OLd51CXySy znuz3dEQuT_y+Y~#!gU(cZJ~(NGJ(kod~&Mz)5_vRU1c#ROG~ZjNt5?%J4<$VIuF_x z3y$5NXS%}bq@5~l*ZK0N%;X`JCJvO;Et^!!HDyLtMNPif-f<@5!5<7uekI4H%^V-s z`%(I}o#{^PR&((1b;qyR>}6Zq2Zdj~1L0!Sqne|1)-RTWj)u))x?}3MrOLvlq?(mh z>St>q^EuZ3j>cS(u*O1FB3jBc98|ki>+~7%N*-DJT_kl)8*#COzi?;oQjsnKih9az zt1&o2lHo<#!bfL0H_eJO*ro>^PN?d4^WkfSbRF>8P8E_gh>ObMpFY5p+JOAB*#tSe zl6AM8z0Rx#g9%`L%j6J;t%gp5b@LxUKsjiFM3Gl)X8M`1sO5(%OxFo9xQDda(NHua zr5P2bG?4hbbXicY^EuG0>lg8^veaonxc-VAv^w`wOur-$SD8~UFm!lX0P6a`w}i7mvcWanLKj9JtH_S=Ge&%bZ=!_lE(j;G@$_+BMGniCkmg9*~#Y5yut<4*|sQrNkWG&ZwGF{=TrUOc=GQmuQB zaodIcmBy$WI8aDpSn3{8FJSV7G4I;!#Z|C2y@PC~Q@Muobl7+lr#?Dukrxo%$f%TJ z2jmu0jM8lz$QBY@hDHfy``%mbRAXD&zi|V(cMuHehPksdI9O-u_gosvRw9*zs(5+K z3Y_T~K9^sPIjj34T3{SpGW90;7^t^0Z{_l{c2F*}CzK3}>j_B9y?L~^6|BoH`D}q8 zDaCBU)*w`OLzqT#p7zb&s!TdR2W?m)KO3W-u|8tNlEtT%FgJUUxqN-ndf6tG&=mRT z>Q3*9Wyhq#$NwmirJ}T~psu5cmup0fIT^ttCq_XMcb<|xZWlo$bY%^0X>*r$+7UvaI_AyktASz zm4axbO%mz*{8Om&h7!T4xL?jT%#@zI2pYd`EdyQFMQdHlOe_2gH_Q3R0+a?@PsCNV z1?^}1S7@;KLucWzw1aB>c&ri{63!D!p zpp)i3wp+j?KkJN{lez;73~5=>1@#&ffPFP-qRX_xHRdqQwyo|yfNh*pq=_n{rT^mf z8fIgsFNB@evwAYlb|y{4-c;M2tY=&h+_cYa9zoYNre!yR`mb2&;i$3SdKdgCx7yn2Fy&+fu#+%Fv)6 z$~v^7LYcw5`Z;hY66hX}K%P5y&d4z0tSUXoI6j6aYMDxj9D|+)do)h8UJipbv?IXj zzQ|tg|Kj9&1+e_@vk5SHFw42V zAa?M7G^EAOz-0KXlIU9QmU=)-e@{lv?gBG;hnp5J>ii?HHsJ#$IGOvHTfDO_{da%B+f1i-I%pvPsU{rqj3j@vI~s27 z!|2j!eLl0~@l&O4>rMwA+;y2nHQA*=opC^ zdMVUAtvA4-p(`QqDFy%CZyTN2{qD5V3KQHOAKi2Gsrmw&l%$dQE?qK5Zt?s&(}j$W zXEQ%=8(G_vPh!#{>ll6to0RaU+ddc=xZ@G_R0$ZAZFgzJ=d)$lh^6D%2SJ!oPqkCz zomP~QOIkPlgT5mEg-dw5d*4XBb*JBPI~Typ6xxUG$`mJMbom+&EJ)0rL%E*sdy{L= zbfvc6F}YgnK%v52Zf&+022ZU|j-uk$u7!xh+qTK^Wlub7Rchh81dcmic%$35f(Bwc z8lJ|h^@{m^x6mJ;m@nyh)KnSnGYo{J%rRs&2aBmtNrdLjpu1Hg8}Ucy;jCMNo#sAG zKjbT(P>QJnB!SH6t>^+dF{?6~*X3%%N;T+oq?WH?CEgqR4U{H-PR0Uc^DNi+P5w|I zVay3$&o7`n8?obpLvuQu^c01ou=;flO>WU^iHLLjFPs{Z=Be$k&$!7v#@Oed_uBG2 zo4iH{M;Bl-0)X5&md~KDTuV=@vk8kHi-aza@h34Ab6QbAGV4HK(l^90w#x+jfVf!m z5Poa?GPX)hu4|MX)~QwLI~PiIGJ?qJue3{HK`QbFZ>bl^FYz3s)uC<6+$8>bTx0~H znhS){BCJ+hrgF)+WKd*X4jU~l`jGjMo3KaU@vP}zu|#CQKPj=;7%9M>IoeF>$=EFS z0;IUGP}@?u3-Gy^uOpwpdft~F9pJS z+Hw>8{3Kk6uXa@jOY3GFvuTJvc3o-jH>VJlvjOgG!SsNW8{`iOdYC&r?VC=S zW^dY82p!7bHJrV8 zW==NBK-{@)``Ll9b)gU|Be0Kh*=bnUGr!3y_j07`)3XaJ4pT(lRJy$VyZkmiKP>0! zw)pA&`)ZhuEM=UtruhCOOp5|9Xqv6Zn#~-;FX|`q3m_qt*U6%YIuNuV>irxZ7rQhLOmu8AjCsLa2BBOlUqQ?SYW!X0cS0edd@Rw>=kk5 zfM5zu07*8jM7svPJLR-Za$ajm^; z809&{{{2F69D&RCgAe>Z;yZFBAC$28WW1Wzj~m80)^#mV%7BXBHSy~byk0ZI zD4ub9&rc39`zezm-*%x^_zJF@&eV8#+sJQ#M&pp z{Sn(f3Kq`=*_12%{scgdOmGNM09xZ=8@g{0zFmc+_(Oi%lx^Ow4$d{E>&;iM-bTK& zF`ODlc(V=yb#YcjC58nubK7vzl8F?KDqhbMo`_2f$JFv$cP9htp=+kvOY`JMR-?Jh z5{PARu9ggDQ8vCzz{U60gMaYwy3wDUL|m%6LT!5JB9kQHMlQK2EYy7S+wuNrJdISO zMlrA7>;KlyKlxljw{9e`@XY=vKM}iPGzd(r4wOHW4Fr zt@=vbSnGUdrMkT8{vzrwSyA(gR6n0X7o^QF>+S&eh8P`R1wu-!h1v?!;3yj{W1vss z&c=9r|HZ!g)owB<9JX7UgohXv9Bm6o9c4q8HNF6OrSYKDr7iRiOGe03w% zx2k1tB_Xp52S#@@tKT>42aD*VAw&L9j!!YCN?i06Y+~l`4bu?F2lY7~cf{CjC@3Y^ zJ|bx_Oyam3eo(Z-XuAIHGoHCm1Z75DH~M`tsk`+^pIhtS9XHOg>U29w*Y7kucz9r- zef;7-Cv&s7UP-^#q)4mR2)y*F6w}PZx4Ub!4$O?vCdtCjJ8mP;zJKvnfPYzUnNa7~ zDrM>|>XHeYXFC$d`7#*=anV)Rl+^`1Ps`yq2Nq_Jd>|;4_}b@bed?g=!z%29+{WT5 zp3!xKe7`>QVFM#+p8i7@e(4?d)1mg2N3^EWlaj@-A%|YDhJxPR#EkHwqzAHf=fKHr zQOm&wniijnBcbTTux(f{)**Fl&24Sinx;hPIW$?bcDaQgwHUrD8nMbhTmSax3q|?p zo%puM_&h=xL+b~EPgAM;30iBV(j2*9lXN1ULo=Vu5>PZ9J@04w3qbAeHA-5A?TMn- zyMkrU+g31D_A_}`Qs(rdaSV%rTU2pFTt)u}YJK$A@gSPL0SBqw0W}oUZ&ob#^x7S} zUv*eK%;&WwQq3Cl?pH{X=;T5?S~klYL$TU+wl!j`YzVrAw5?vs2n(X195AiPy=haCtU5d*Jq{u1J6-0$sI9$mh^nY!i#mVxLdTjr#7dix z`6YHf<>%1Bntb++Su|-gt2IdUj5h0TG5?YFXIr?Lys;gkBPTuXX()(QibLHMg0`7v zWOq#au7)T*Ze8(AstM{@;+^yo6g`9~+y#MfH$m#y=;OjW7z8Z&cNgS}{9v z%`<|$k3Ytt2~U6Sy)-z4MCCQrDT7uhf!4=xyCNebFD}fZ(hwASDpv4OP08jOX-QK} zLHPb=yu-cbx{dJnD8EswT1&FHcAT9i>4VHS$fZ|)J>z(U+r(6I} zn)l7o;8*nGZi+=I;fFqC$QTrDa9vwPh%d}*hbLjz&hJUVEB!B2K!{gA78uT69LWV zdgEcfg|)i)r@@N45w_~Z3#G+u)WVgM*o8)(j=0$f8@gOI`JWsj8IMsl^KmnCmb|F&^k47fI^#3YnIz} z5f8Ktu`YobjlcUyo}xw7ybI<-%&JO4($xSckRC_q;U|-=T$&Qx%Bn4#)y;gSkEBU+ zkXgIs2Alpqyk%6HGz3MCE>mX_LSz9ht2!-=6Y4xCh)PV~D0>nXa2b8r4GX?+THy>D zWpsI+n!ED_i)ve64JEE35sb;qnP`%|gEpYG`K0V4Xsak$2#WQzOoP>ZW~i=$C3P8a z8;$w*1$jS@X4ZK-xGJ46fsrHQgnuuj>3L-$;!&`{RGJzn!~d&X&;OVSP@OcZFz{9x zr`{FSn3a&l5ye26@I*u5UF_~i6Ax+#HZPHP>KD^5N%ZV#O=h%~>XNMwNolFh!>~z_ zuV;_l_M+V#iSSboGmG4#PIutVEe-MH_W(tm?dXkuXF$Tr*bu{8@E0vQa^@{-KZWt2 zkx?|m)AZ1x(&7ZN&iAYqyjJEkD zQ~oMyuxVD+%_ls=sXZqfMHM*@1jyaH4n zIq56yi6ZKZm!GA1*_cQU=-ir}mq#|y)yhv-Z_2Qqc{>qmVlL>Oib@L|#=BD4G>8#Re&le!JvA8BLbqGj`|vF!8YmC1 zMedCM+892+o2+}7Eo+%;ZdXSziuiVx29_E;A&*%Pf}EOa1^b;K;8t7 zjEb>{Iu-Ifuu7C<=l>eivPv@BYuEtlk@czN!q1Zug%rqpFujR8v=E?S!b#9)j(%P8 zoq1KQcV1Ql9KDKjBjBu}%WrUqGc*6p*RO2gIf{nT>P~C|B73 zh5I$%yzPZJdG%?rKc#a+lzOOSDqTjz{Nem4mu=fEvf-w>DQ?lmQmJsgpj>a8M1&`! zPOtc4J>7Ixi&$Y6&uZdVKArCycQjGUjl4aJH8YG%S>{+4ZHVZAPs}yn-0$qs6r^Eu z`}?t5s(dY+m5?#d&!RG$H28G2w<>ZbY3NA9X4=h>MVJ%o0z~sALs9!-1e2LdQz&L1 z%*3dAO?W^}fi%Of_({`+n9NmN*51k5)tXo5)WgmkM3KOD>zxloX2LQV_|g4cHN2RL z4@uY$-3cBux3oiQ%*=Jw%%tc@-a8(U3Jn#550v;X9McZ@39KXkU|5z&4eAg4O~#gk zf}=11%{(AISUPwcwF5Ft@Y|}Mrl#VCs)?n}=Y^bLIYRL#uv`@=%+XsiTYU6ycz{={gmSW?y z!Nue6gRnt%CHDK?g}$d(35?KMK@8JSHJlj|GP$#~WI`aAS+(Aj-+d4Py z2Ut4RZz$tKDtFQC=Q)|C(^nfd8q??z6cDoohxqD3zO{@cg_0<1^-&#^VyTd>44w}a zifofBaA5aj0oJPQjBZyv)1atRT?CZO8JUjQXzv37c72xk^NpG^{u%JkTt8U4VNg{IT(&)AN*@kP zQ%6H(jYYhpL&K)8!t>7DOy!1phnF%{TlOv^j!X(6O=XCEU@)~N#pB$Hj0T8{$0d); z-66LTGx(eq*3{WxqEX@a6uiYn3UiVcv3YTEL(GIOT6tw2*uSg5h(_h=9xCWwI=wFM z7`;=jH*TDZEq*vTPvw_}X#R!cg!E)qi#B*MM7#~(DWCp1rqahFmR({CR*}ic5w%%= zi#wI6_yVZPIL&uqw%xwNTAMRSDH{y1{+THLYehb?N ztNx3D`4bHUH8Mw1v z48_(AZB3?{G*dXKYADC}mB0%=No_rAKF^Y(A?+#itI`>zTKT~Cu=!9Ur5QM6~APqf7w9a0;< zi;j&k^n^AT0x>`rz59p3IgnJJ%nuZ21oHCNWF*MDKGP9fBI7ZNi&~_zG@Y?lixi?-L>q*oah!Qx-ezE4JpcE|bsqZ+#mfl=8I2*2dXN+N;UrB3+f^*!_gQjHQ~ty>Oc;dQ>-#+;u`LT9+|NE0Y?JhuAA z<3aACLvIofbByp9xE{oSRJD^~6Ju@A=CaCUD^t^K>W8lpPt zb?3|GG>Q?WTXj$qnJpk~T=wpul(n+YsH}7(w0cUHsm;oFGQ}U1Ay`0aFqg9?rh7HZ zntwG$+iA7amq*`>lg3iCZ^lj|0TuS|rL5dm9nzj5N~W;k(T#p2@_qKeC3R^8uMz6_ zSh6QISJZxDCXOZ@&k$aIOWvK4m9id*!yxXSs^O-uo}#-aa)pCJB4K$Yi9fXtG0|mo zH#94${c_Zlb+8~l?ki8zd?A0ewQCj^ycOGGv$Qe!-`c4DId}d!cm6qd{yWZ{&%)I( zn@2Yd*~R_5)Gujdy`Q8$dEm-PVap9>l|ZRs+`_iznL%gOy{ z%#@Z90L0;k^(5-CXzN1})Ah7yw1SC3TyMU~k88cB#=i|UOVLWZZot&-$yl3sgXqz+ z?mhp|i@9i{p-b4^U7~I#bm>SpF&8&WV1LYA8RpH*_`dNmAfe7vJ?WjykD>{-!dBJX zYE?aztD2ZqcRrNb@DOg3wM{mD=rApdZ#ZeQ@&vE-?U{E?DOeKs4QPfN!{M7CyE~nk zoaWLmWFb50MWmMcXE!F*dwE>62u@J4HzynB%DGCGE{7w@PDCXQJlUG&TefLEcn)1E zqa8#%#==I7gQVE?k@w8Roz5-FOfFTK=Nm2)vXu1KPTZ$TcX>|MhVN9zm_B-7_Ovus z578*{!_AEmLLfHy&Cgp1<$IL?=Xu@@!`I_-L;l^{FE@}@!cP%1T}0dRQw`n^U&R$~ zbnqyGNo3mcuuI+>wmd5b!cevXAx-*)oy-03Ade&ti(QHiz$8$qxXZhmIj*TF;K;P2;!{KT4kJcl|LEkee+w2*b^-niVy|u7AGil622O0j$j{he$vf% z@Tc_uVksC-{Wd^zrb8pfe!s}dTbO+h@spS~>B;e?sBh^P0sXrM7VA>!3XTreP>yj! z6To?rU)J1P%~q~69>wHw`9%wCBE8O><@TDOLyp=3*;9^p?r&w4@OMvZCL#c5m{U_j z>@u?Fk^M>0(>3KkhuF$QT7+sGDV-Xi>PbPBu^R^YD`T#LEQwW(qv~CYtv!A4K%~uk zy`i+!&$)??!+SNnerdCw8ofRFm-EtBng;-#^7hBA&$~mN3sP*?I1%^3WE;@TZ%bHS zAnD0Cf9q)((mB2;^yUPeJj< zl3&c07x2!>_l-ifCsp_au(e~c(SfSFJ0X{v>`(ozr)voiI_)jRE^nHAxlGoymoH?GviY?SHY7OMEw+ky#uHNLFtt6s6p`;n2SV&9RX zPB;@Z@3l1)ib_^5+1y#PqH~c=4eQV)S)D@~KqE8cV!(^;oFVv%N0FWnXM@ldjKQ%U zE*Ogci%YCMMP(fICrD#WHZ;w?Gp@D{hv&9decY0`BK{lvcR(@^F?M95l4YpVufi>( zOo7mw>ObJZT790N!CdJ9-Sh(zR+byRxf}%Jq|FZ{XVIXAFcqWqIc4W+KBG>*lIjnZ zn?3%IvAR56a%{UlQcJWrEKwQWD5jYDZ%h{{5&jr4K_mvFry4S7B3C<&#Z8Heu91X+ zY2c#sYRwcRD?LOI>V+T~Nm#_2eqq#M`{=#$4}k_Xy-pR*`Gx1m9QN;qLtO^7?{#GC zRq2t>DefudEW|1&y2JM zmk5;OcQD|ZRlAKhT;cN@+-NU$zO3i`1mwSPpZF+jbw%z`kkx`9*qccR98!KmuCMUj z7=$9PGuo@SBTTyS7c?dXM_m4 zKe>WzfMI9-$;=W1*CrCu)f&CRX6)Z?@wmkRn=+ zf%FTD*H$Q+_ZJ(xqzRq~E2S%bq+WNaOvl032wtZW0@*HEd_Z!<>L#%wz+kj-6wo@X-1R+Mbla&X#Y^r0#6fPOOrFK?q?=DW!F0vtm1)=+zHVp1) zLvzgCiV9@)y=w1^t55Flna2O~B-(%Od;jBj{Ns51<9Pg!;duOzP0}*;VVB|OH504Q zd!OLtPOePOMkNFet8MH{ z8=9SEQOD+WlBvTZR{1`AY9|R{`k#Gm0Zl1mp9S-`O9r$LlcBVXSolQibratVshsUy zxV@!es!g*QNv(^?52axpt8a8S0UUPx@#3$E>XNP(|0v4{Bchk@4E{NbzPAWT=nW?c1B!Z2G)AfVS^kZIEsx4()m7j=!`wI z8k%UU)0+@R!*-@R*!JF=S6m*CicO(s9NN%MNswUL4fpd{VudeTpl-FZ)x`R-D%of9 z%icaVzK{D;m|f3YvBD`gYNzDbmQZfLw(^xKDC>d-470_$l!{DI;pCTJmiGJ$r!Zlm zU=(@-sI*e*=-+M7#LXBIh7Y770utv|g} zs4>G+SE%aN0s$RtrHBAa6W4&Nx=pLvYAzwP^dHL%R{0Ukr4tM-lEX+UVGg3nyxf}8 z6Oe-Zhzk7qvq6W3ss`Xpf74Z?HoHD5?I%u$eID!d_m8-lAr0{MxRyk0I!E`)`#ke& z5q$+!n?D?ah0dQ|^C*|zeLnJOgko@R{Do6>0v6ptD&8_%?sq+|Rg0K080=39j)DzxgaPHprq^p~5f4Ny4{ERVycI zWNRRk=qt-*81V7ENEk##Vk^pJxmD-G<2593;R#P3~#w7lhV#9M_%2JR{rA(JSHktr% z7;0$OtOc4T^V2bCyxTWV3@3cs7l}y_u&CDcVCofwz3QP1c#l`BOwR7OP`VFsh2KS4alg3+8&z7! zZkr81De#lWV(1hh*tC|a@ll?3_^fqMbp#22Sf+EAYFTbXzfVH`rTu%=m6#f-Bd;qN zwOBKdc3B{wV;S8kk(4o=k##n95-Ywk^wQFhbc8k=`h#l2TK8HE;e)b-$MuAV!INq_ zWHMBtRB1_5O8>$;QQmjI{#ABfsbn)hB3X(_H#rDd@`4-rA{X%mztwgAc10U#u%g5T?<lmpjVq&Of3^` z)v|i(Kcb!4eTt)*u!!|gYhgm*%y3u~rMGXbKU{=@qzv%J`i&qIY&ShJqa_qnehjII zJSEBiBXQgKgsk$e{f5qG+BTzEnj@&jOjs!zP;H!}8_B{dGaGWU{1r z3+sr!Ml4Y?M#XTZ+(ruplGtF#6);n?RvK0Hcy|$KYI>NyH<)#8_z@-q6Z`U8fp%pm zKyP{E|FLKGuN3*O6#1_d`QIr;-tN~Xjdf*6#k)?pxDOg^^fghcGv%W}b)S^`k}ulGCh>!~2ts`D)eO zUZd*bjDah_^EhMpb#Fg_vO|)V3|LnZiddzbRd6%p5v1=xQT!Q|=D3$Ykzi?p^jbqU zu$m=dr^5zEiyp_6%0D3w3Wx?CKYPg6u{m+HBxBAd;(hePsc7K|iYO6Vs)nk4Jdy!+W@ zGXtQ*KWURT32SmYtEU00RNLtz54AXwmxQD+$eB0NDdR91jf&H$DnQPglXY>HM*aE} zn$;ilT=(%ae3zI8Fxhfs`jqTHK=ewS-Jm?`5wsE57bY^({ZsNnfI(fSG@Y&p{8i6a zrc^`DY=`QO_#)F+EgUaKs^NMCbaWdFJosp8raUMw4!0Ns9|osv>b*k-w_%DiFCrOO zA;pDkWLJYm;}j7OZ-vnq>%YeV{WqQP4^s0FQu99!QqwJ1`y51u+W5mw5~kg7Uhn%S zufpn-hD>$4_%xHnV4+P~x#}$;VT2R=+|V>Tj+sFkMkSqaSe4B9q_VhvN;t!rVbQa3 z)oux>$$s2oPz7e>t7V@pg3L~zigIWceG#oCAi(h+AD3vn5jFsn3 z0;2I7*eg(*yF{@2c=u(vF?6{j>Y9gfx_V6VM_+ty6%JAjQlk{K-dyefls^*I{7&9^ zW=$a$<+UvEUNc<-*}XP)<}Q`Y_g$RoMgT9?tL|>CuK6KgDCj%?On6dDctldDGTb&a zT`tav&$@EJ3TCC(LNvsU&5b{!(Bd-U_2~h!wS*PhWdv-{yyZZCQ@l~Rl!T$k9ISVSA-QlXT4M|Gk7rhz zhjfo97Z(v0E_#bW^fDX!NewUhb7mz=HoP^?0!lpoDS8cTn@pMBPQ`{oD*__IN_SBp zWkyqxKx%=aIeq^Daii2!i^k>Z4&9o|_K$efiLnF``)jQH+zBFlD{900R#T~vqLYTY z%A}moK~nW7NmJi!$zvE#EX6)ql2aFxBffMmlXR)VUpN`c;#JcBT*3W+x$;j2|C7Q0 zWbi*3{QpN8?7#DKUt=>{PqXFC?oM&r=$Rx+tWmvo8sk?>bqDV4h9K z=$O&!SJ^ns<6dK#4{83>JA{tIPM%+nCr7qjzX-)#jEWGN3Ba!+=GxkA65v^&7nmn0 z4f2DN)e(G#<bKWeU(osLE$(A2kl! z_by}X5g<|~zZe`wOE9W@(h0{(jQg+l13^x zjEu-FDWKWqMo233b+y@6;||?tByT%|`nNI=@|j5RLON1M<*t`U49!E9bccEEDYP~7 z=QrQz3>RR#8tMTKZgNbh&$#=+(AjwIqGZW5aITibZX@~ zy@)$>@me+huQKpHTm$~Yt$(R_|5EY(rQ+eR$$)5=l005?4Kza8CCyKfpSJ3$4oSy- zW-gB%1bnm`r>VX=1Hd?-!TRbFHN9Hk*Sy=#>qCKkU3DEC%M{N;`=& zON-dhH2YiVKC9~}WD42YO!6dJZO3|=I<2iB4`dUpd0UyI~DRV<)KyjQ>eMYr_r~(0jAqn5F-UfM^RTDa;4s76bblL zFFyQ*i~mze-dL?!KaOf9Zj}4uM19L{}LuT{Q@NT64R;e4kRh3z_g@#ANcKFCofONu-RO71{B*thcpIU5t4gxqObt$RHHiGhhj1@-5&w?C! z#f==xscFU%(q~)aaZEQm*a(jt*(jRKO^sWf9=Sv?+!&y7>d8++8*6|DEj}!_c>?ct zt$1)O>T|LYK_lEppw97!Zb&AyA;lQTcgw?@C}^pKJ;wSI&sL0YM8mQ>+?~D68Y3*) zXBgSDk__8LB?b2;nr~qE1y!0>^e9N1bFIsZD(7UVH7S=;M*OkZ%3?J^6C;~t{!bmj z_JT8>jy6{o%V}daeT9`B|JS%j1`2m>8*Zf-E#5CUEd3dT${-pmIUA}xTzC&I_MLap z9vRtiUB2llYN#YgV)-?pwbIxW{%NPV-`YnODQsZt6O(&?;mXYxN(T3=nbxt}C$#o# z372X0p87+$a5%rSf`5m|?6!wV73YB)3LJfD7!|qP=;`QAn9ux8z1}Hye+7w%2k-Je zzVzpia;3ZLXaBH0^A^brL~{*_(!FE1G>u`G4QXC*Y^ZoRISbF%MN6?@t%PSxCcSfL z*8d9^rtOpJ--TpBH`Xzzd5bOai@u($9XeV5aQOON)e8~Vd{QPR_tt&UQWPty-kknC z=Hh8urzF$Bk6#4l+B1nJ^OL_ivvZ(g8h@v;OYc!JC}fr6!M!-@->p`Z+ zldv&JB222NrW%Ryp3**r1`SpY;DqaFf=$ZkkZI?sV> zssahCdP@Bv<5`(+aJpxkO5|&9g!1wi_&ALiu38QPxYQ8wQ??EhhQFCx0=L;Ufks1( z=;GYgc*ZYEm^W5;0kT({J~dum5r1Z03kQGU5_6qFFT0m6V=^d8>GaK0L!V%CTFw45 z^So{4#(K*tdiBhi8DaV5zrBp*pGddEeXkuD%2P5UG!nM0smOO)36soz6D+KPV7ul1 z_$}Q{0@G=mpS~221T=5=et70^-4kiOqWa@tOc%Fy$QvL1gIA)va z;02&ugJ80_b@*4*B(=vqg3kfVN5I`CtoSHUS!7R1xe4Xf`KFFHW)n>A=Lyb?>yU?~ zebQLHr7P{i)W@_-Z^0nm`3vWpqpf0jmJ?mgppSY%*rm*CE0n_(ok1j9UFNK15o13+ zVu^PCS;U%CQt}06UyVCi3@uh}B9lhx;ElALpeuO|th)^IN~#Bu0Y_aWEn0b^v|D(Z z4egUOhXd-;$*0(rMo~%p;`b2xQO6t8Gm*)aX4j{N`U20N1+u7;U~|nJSy51i*6AsS z&Ti7xE@ot@P3%6pbN>?~Uy>4bs5G(p$4dSRfgK+1%}OAL3C;8~2>RYDOLN)8$yil{ zQp5iFxNMG{OU^yLx*HvP55Xbvfa{>YFcHDdfuM`XgjqWW z{hW(s-BK1!KRJGN1Sd3;rfEcNZ%D?4^BbLU#dD5@a{N4R9hFw`zze;(oPrQ{RjFWmIviSFADjkXh+ z)|mH9mheLC&SADnDx+>l{e}Ik%;90muc>8j*zwa|LIi7lMC&R-wDi~j4LBas_ROtS zR{I%r3pvRU4N(;k=#$rq(|^#?|5;uC=PP`~#sdpS_`{v};!xIEV&J=hx#)INxe9g; z31)UYQs{-w46bub0>yD$+ve|1hn%C2#|eBz#Gpx)vsa{ zWQI3ripmr9q_7qu=5s^zL}Yha$XCU&S%6BUiWgV`hZrsDH^xmub1`;l(~%HF0jRY|}ZEIP$xKm?kXl2sCxR zB8KF>=?l(vW>g0$vIOmoRY>77;s6opg?H(+gKevVY@^XyyR-5<$VCN5RGoEg*Z48X zE3!eS%y&tfA64BTPw&%!EgmBm%O$vzj*=4S{z+;jUdI%{O$%Z+WhHxx=6+V|p+;)@ z`3lFv<79hv$a?0ROu<$cmEEVQxN7Dwl9NUR-I0%*W#e^N+M>!RPB}+{Pff3H^yp9C z%i7iK_k^P_G|g_N@ISO?=H#6rm|tOES=9a%cgq8UDE3S=UV@_ZQoHsTDeGC>)P4s9 zxcun^_wtTkh`ilbwd($yFC0?`+q|Oa!2JQcI;(*3F%}m`pHIMW9)v5Z<(>`mj zz4ltun!d=Qvd61e@M&QU3` zyz~gr1mn`{JGU!idnh117;+s?0(+xr){@Fp*AdT;J(v&|{?er;Sgbp*iFkZ~-Q7Q$ ztiG}m{QE41d2T&Ps|+b24`ylL=x+3EqRJfH58(^h)j9OkNy+*gpXjk@La+hj1#s>3 zCtaRTAsUR4)}Z3rPSD)b9@cAVcadF=AdEq7X`$&CX!8Y(q}+`Yw@!$BQ1OD#a-?2q z0QvSQY8J{zGMUw6t=tW!hx;0#GBXg_2)pkWewyy2)Ue>>B1(>k)VErmsvWM|<_$CZ zqfOSmk7XWvy=>V8CD~Z2TCT_FeEBAx834QVkh=j65aPLHTudsG#PYQ(XKdsW-i4TI z+K;$hRn2&g+2tUXVAqhJqPDd(H9%~TuQTNvJ_MFRQ+dp5iT)*6Yop?+(dwbNyK5C}S zw!!fp9xZr^Pu^cXQfLzs<9m4=NG4_9Viaw8 zf`y3R9mMmbp&-Kr0`B{~TKEWq>1T0DPVW5Q9#m!rXj!%5 zWLAbmB$&C_u|Ha3J1&3LuFufrJ^|EFus&Jdv2%k}H?@;%!t#jtok8QE4Vaa9zkv)$ z)Zd^5+?~}BR>k7Nb8&sqy!!_Os(BB+lQL{@C3Uu1x=Ce^;drhs{g|^dw7^VO++}dS zys331nbDqM^VkG+{d4Ct3&?2)7g)~_+XA+w$)?`~;%M>GMe97p7@N6mpzhZ5aEJ!c?vn0_UCWFl#-q{}tKt~st7Z1AhEQgAY`c`!IVfasB8 zo@5{OsYtYYxmomANKB(7Hz*V$ufV~31T%@c|5!M&=YB-TKnTw;H z{(ea!@J}iH2W!GGC665`(#WOsDCb%KZJf&%%KLaSJ^V>Bxwj2#RL6j@EvpOJ5+(+q zKJVb}!BuL4<4fU>NTOdmqUn(e))$hL7G0m|@t0e>AD~{X*LyPHKBK zZf-6Yxw!v2*Y;aVE=Ta7f4X!(EtEgcqP6m=rIscs z>xD^+sL!x}!TEgW(^h`W`ZPmHTQ|-@-0|(GO*rg37ohNYHuH0TjCHii#^F*b9-8J; zri=d-M{@qb#L1JRD^eHB!juE{ zg@UDf%f={@BU5Ebtf%&pmMz!hp@MoDe`?H1n1Gn}C%fux2#JTt*{xsv#MPJ>2uB&v zpqCdfj^!toUWPU0N!Gu@sza@OZuUE7`jmJ zm^!EXMbjE>8uoXmqAvrMk(Gm@oC2;`VE&ZlX2%dv0p5GHcM;V&atSh}+p0(G^6BeG zHC>JTTeFM>*f0TBH*9GZ6-{($d@K>iXhQ?24o$UJh~$CDoU3C@*8&#NAWz~)ab|C> zZz*7Eu&fx(vu6CpDPDJe%aP5KKI}&Bs(*cecGRgKRtxtvZaIZNy*3D0ri~0YH8A>< zSYWySn4sZhVB6_Mg%Ya@mBl4~S&T%-&!bNgjFL{RW$-OAs|G{N1T#a3eg>K-W*AJ- zhVV_bN;=RFM%3?Du#9P%d%ptz`G-P0A|OAK8mA={lIrrlol4b(P1ho@nD>{>_2n-T zYqsphh}BdD+bPPuJk2$LR)!P!#@)Tnuzefv)=S@;fv()6E8CI_$Kc)VC0ugq_Dgto z0~P1xWJp%|L$Sca28>Pf{>T7ggv}=#cAT(JqV8aG{3714E*lCpyR68t=AbVMz$m+` zt|JR{sz7O+SxCKL?%+nev7Q&R^Q;<6umav~4%1P=yIGIi_jy27ykqBG3(~l;XI9j% z1{F)e>6?d7hu*uf{DO)-YDJuYW*IzKBORsV@d~uTfq7!ONtifUUZQQhKpdNWw1x`z z8PbSB5_7b|Lc=&Qk+1Og%+y6<v%8Jb043%eaQ9YSF?#O z4Z10V*jg*}EBAlpsa-PnMp4Su#QmlABwsIVu1AI|M^g8L)a$T@h#+eixtQarc^-H^PK-gT*M<)i z&v`2LH`nG<=Q+EtW~Bqa>B=?|$IV4sQ|$p!oQ6JMP_=04Jh$41RZ|cMnBAs56oPH- z^B$t3PtFti&#Dp|wbKpCs%L$cEU`rTIH+{$R4NsAk|9xUBv?e2m(J>0ux2OGW}N<;bdzqTZ-KY7I2&IdHL*5va6 z>c}$;Es$X>mtq2`>gCVw^OMg+c&G@KP$p@okoWwip5zo(?B=4GG)9oc}%#oZouf5ChhNE^+v*<%+ma5FZ4NmQ^&7rzE!&SAEIam4pZuH)4#NIhv235?3|Rpa{sjvr z6yHlYA`FP1gtRNs=h{HaS~->bPeVV&QQB*2Q5H^@qAFosN{V5~ne_a@e=*=`lj~4j zLfrwGdBpf;EQ(v^3xs4c4%5+&usYCPx@h`kZ0{N3*P;k33(Vts--!$-P-X08l^SB~2HTfp_ro`q+NEBQ zw*K7wr~e7w$#glnLOhLyw|Q8*%dtM~UxvmGusL#Zn&a5tjy(e|&QA5FI=xmKU{o#= z?;&8)ECb7>4q7~!^-_7j4n$i`ELLSAcuD-0=>#vl8$USsgi%U8C08(N4 zfJT^X3=H?a-T8Wx)wrdHrY&)2T($LbsjmSXjf?c!|E}uC)bPYs%F-%RJ-N}eXBe9A zr8%PFrCGTWUkA(RRbmqgQ4(;UuMIsJG4$DY+b|>zPV_t25L6U!E#1}x@8XS*bm8@l zwWV0;HMnkMozbfPg3=g9eXja!M%_T?cR&W>nrx{@A&@#tX`!#=D$asp{`o*{Om#Q; zUpx*JJ(e#`Nq*#ha(m^ApD?{qJ&&>qf_fvz%UHaF?Cmz{^%LjBDEMZLr-mV9P)hd< zr1$!uljd)?j^yopL+Sz3Qagt6sUxcOx;^o5@Ces~aL{7goN@yX2={S=Ll{ zBOROPtqsSma5^vS_iOjmEG?k>Z!v*Yo57qBLO8s3YytCVkz%2u$<-E2U#Ba-6ZBRJEPfR zW8@L;b5PBZx}eX>&M)Z7PvwcAvg7O`{)BGj7OmeFqOzzDZY?m-O1a>W`KPbjPB&}` z>&z~?W9P>BNke0CUxSd1)bOSEheo;8t>D$7ooNL@(s8v@8%CIp2_jOKv~FIUdM~Yn zr@CX4&1^gR27O|iaEiF9VN+kW%)5O74aqI`{GM~JG_g-(pr@JwZl|F zH3s^`3&x}KG;`i-^fB@*bDMULArMA;27DN0Oy-KCeyDyRCw$HW8|Z>JCiY2J4C^p) z9S&H+EA#@C*EO+Z(id>Xl1IpRk}49S@sJtx>M_P5R7~)0tOhvB!M2LUD&S)$F-9+LF?)8z_uvCl(%f+bC;el{;#z%nfEZ z7vMt4qljH&c_t*S%+favM(0tnLa35}^!UJ2(DB0kn}oBHJAl&xxrqq%OA|h79q|c- zsjt7irh~D1of#BYwlUnt9FADxAdlaY%NG?RrH?t@yD~Ae3EB`8#ZFZ%H*H(x#z|_7 zANwQe*vLPLCB>J7KA=Fee0ez2+p^B9@9t8=prDF;c9Ch+PIMThbV|;NVa#{QW2A@W z-f+<9X+busY+YF5a^V74}?S`svaRJ$~_ROX#j7R~Kz^Y}ed>)Hv z$}>?fuiy0PY?bli^e=qZjqOhzJ+pIw=*up3ajSBiC$@vXc~JATVCWQWfp@}?Xz z*5G#^V0qClVcj;*Qj`1-hT@&RtF^BAxtdZiZqU%e?9cj#rxvHyS6qIKia!1b5dSAX zyCrddmWk1+kEgx5EEU-o)rp)_Mo4+&E-F92E9WY<(zd`6sYV<`pBA3$S?DuDUulVp z311$`%aQf!VFVjb#l-+49JV|7Xyl}%%h|+{bb;$zeYM?elYOc2kag9zK(DDu7Bp#v z+mIB^fRmG@q0CeJL0;2nhzmbN-|fJi+@O_F(=&&2w7l1^jkz^)LdLE-Lf@Yjmv-o9 zI>9$RB6Q2B57;9rwrP)FDr(~G0mj12mSAh|x=|s82>82QZ{b*lw`o+kpRcuJ=Y@aD zA`P*SliMcwGteXHY;ni2OZ3_i+kKnHOK6K1{b@|mRK{&gmJtjLD3yAQV^7AWeYE1( zYa0^~sA1%ZbiGjoqtY!mCOW!(yB&Ef?AJB2_V%Ic6LeCgKT9RZnVdKcnK;tf3u)XC zxU6i=Z=^RK{Ow%Ijs?8AqfyP$XSO*nYj^6^ai*umh$0A@7wlB4L#R0q)K#;1teGMb zj6|HO3GJJzu0WLUeGsv5*c27aU_d-DE9MZVX1be`b*G)fq%u8o3VWz#q%&6+(;#=E zEj=ktNoR0E9tmJ&Lo_mOK?BV?9*M5T$ZJb+*yBqj`3Gb7f0@%+@So>&R!02iIh~c~ zVx4wOLNz#tgb}k97sDT_kCwRFg28{j=mS}J<@ED)3jIRXLP}7k6j7#C`vv`TgRQ#Z zp)819VhNyiO)K`j%*O!h^J)FV*eY&vV$yq2*C0uo56S0SRMLtT)Car!q7eKHz{J-* zXRR@#XI~}RtA-$O=u#Ok5tJ?9`=1C(p8@c`a7CJI$sk$s#HHEd(~l>Yv!d#CCD^MP zi7uV}lw+SK#zCRuV*uIJ@5Y3|CzzXAL@7PwsB-h1TMjp$(S5Vbr%l>J+4$Upk!2T? z6el)o)8@n~U!Fu?e}_%RSOt(Ss&tcnP|O=&5DS3;`h-4mGyPwXfDR~}~b@W5N z0u*!I(f?p1w65<3ikwVR$&#qqtoa#VMV+E~#1NAkd%3#Q~$ILIy*KT`XHvuQ5kg;!378440)cx>4~Dc%D-*Fi)b_ z15s_rA>N^+eZTVjwM;d2_-GLHP3jfJhc-xJmr}5PC)83r^8U2>gP5hRHf_%#T7Nh0 zqV>uI%fO4a;xxUP(S(Mr(8hj30$6)V#T69*Hpe=WFT~>EvSjU|#n6~JJZgfF4OmCPvc4@rCRVyN4o z^;Zgh!{vG#@P13q7@GYJT=nl)^eEQ3V-u|jTBzEw`muqBz96&_(q*_f6vOFH3lwH? zY`H`|L}-tXci;c4W>w-;xFsXnU!l?*iV0WYlU@;^|K12c8&_BkaQf<;qj=DMk-yW@mff4EfA>G>_Wl=> z#iU;2sfYUh2Ov5jxG zD`lFWQdKhz=489y73`b|Rdmh9e!Gd`Rln&QaFs^|kv1T_r<3%WV%WI@=Kf$H?+?L~ zvU9t!p(su5=hLpKeA3~NT%y!80f#3__VNKQ`;4G=cs-pEj6~#fB+e4wg#|olcy$dB zNx+vt4tnwU8Bcwv+Bx?gcbW3Ti+}gbOQ7J?tZMSpTlT3mv%e9nWHWtMC^TcPfwae} zWXbkSgm(v2^>}e8q}e1u>LusJz?`D9^`0WAT{C0U&n!QN(X7jH_v`uZquFmHpA&#a zLyAgnagB`5S7)5D=ltjDjAfSCEe88m-5>gcmL0=1 zDnWdwJa}Hjves|bxCGR{ys8SDyzcqEfqv9j(s))rCBm9Q&GU%NUS4lMJ4uG04vW{H z6wQw5OIj{0EBo~2J~cge(hzbD>4^y7t61eDVTlW7yH34J;hKK-mM|cF){RwPG4IR9 ziVSZiW`8Hc1&Sm4(1NH+`H2KDHqW>z1C?+;?Kwg^LuylNV!M-@)9f{L+^TL5%eeCw z4*1o8lu2WDv_c)63gfj-GmABoV$9*UcF)46NO0T8C#0yImMBG}!KjD2hSEjj?)dRT z1Gd_f;!GM|oGdHLrxYXuYXD?fhiAqs5%?WqQNQi_c7s5XWFpJ@9AA;zth-;F|A%GO zYk;x^>Occ;qf4V*wb0SyC9RX*_TxkcmcHDjR2>sl7vDs*ImsrZK0#Th4rgw@dR272 z2@CfxI;aEJ4c@SbdV^JeL$d=Dni`eGFhCU0-+&?H>(Grcw)a`Rk6jdqrEBGIDncZ%%l1 z=`>Z=I*xErsQ#DS&fUl8_P8+u&h#IX?FZ}eSDfy%wa(QKaY=dJ^kf23XOD)8C1%N5 z8ukoo|6ump268XBo|Db_V^xdVE;n@UgDL+U$aM*{DVDQT|8V%ZqId@J5}%)C_N+}B zehTFbq7{#ZOw6Qd%2#Z-Y>Ob&IQ)H@Cg%E`kwb6w$&6_OY>zLJp$s6ALxPI0gsBLKE5AH&&+_+drPA`WR2s;&8kF=p2_C~PEv!Lkl@*8}q zp}fwdznf-v6X$L%5@_(NKg`z^J4}-E9Pj-utYk;UtSti>Fp&OE?Rg&{qS=)fRh7#| zD>!3Sk8#6#{cuFhy6d8m;u?)(&6zGMf&r-$N`7hQ&!RGIr@W;2Gm77m zD0Vl6-TvErPFFCnG)g%y(f1B5Rc1B&ZvC)|?#pk=5|LcmT88LMGdX%0j6U=)X7@u% zkhbS~qApWgtvks&MSfxXT0_xMZ+D_G(zDzNY zFg@ORF-Yw(kQyG>NwAjDpS>;5vfgB{P6L@qA%a*YB|^`LV*xG2!}pFPcqFr~THAR{ zqjB@ko5-oEK1hIcj#`9@1Fp$;P9COfJWY16#4_x35*>5Zt5&4#ddjCKEQHAJWQ|tU zjTMy8J|DL!GW<1(tAHMST((PmA@Fw}v{q$-8m5eTQonC>r7$PdzIE+9jyyxT z>)B(IE*K4ZNk`R@jnZoBaA7G4YSQf1#-!Ou(PDh{L5hp#03}=~)WL0YF7BCtILj~J zv}2-*maFJo&!Xp;9M5mXY>;jc)lm5?8qi5D`4aGOij0k2IkIOn=&P#5vKjVr+#%4NTOk^wz- zs-J!2={UCORK; zFPBY>a_b88iB;Tl44Bs2MkGckKJ$jV|202!XVI#Vog7G&QmvVd9hb)HW{ox#94{Xq z!PJ+teTF_dkNUElQ5R9GtNZeSfmvJuwivnR-eB@iwX2QUKiBmQBWUZtk)w|}^bndo z(f@$`2+^xh(Xo-0F`HP~t+hZ%#`tl@V1{fSR&>sb<-{V{_T2V=@3S*@z{_+PP{ZYg zbiDUya4JtewTfsg+r`A{_}RTC`P!+ir?OD7hXup97wE2Unb@%8bGM&=^hw!+EBS~V zHIjSpCy*m@@U#)$#RykNrYF6OM>&V`=`|f`C^L_4A^nlWk4kNB^B6HNn9BkU#S4CP z{_=br`5#RBSm$4Mw+r3*fW0emOTitEosf-1qz0+usmPKX2W=$U>aOCUA@|F6himI~ z-WsACR@oE1uaIt^f}2bzIU}Y$XAZV`Co;){0pqw7YkHV?EA0!9Vn_pVrcG0J;BY}g znvwI7_O^u-eTE+E9*I2;^E@phV}rI_Yp}J5Ty58XvW55G#h#T9Lk&swa|Ej&r6aIt zsXMWWh;Y`d3G@Z5BBD{YEYYWs;3Dqb!OtB*iOUZS**;swcZ)WSJiWbL3K**M z7;U#g%C9z53v_3dQ$(dd6KKHuNeC>_@k~6zb;Zbk7)nt;d06NO2)G2G-!B`wu3=(~ zgkmn2-dSa%v@T*ST&v=Dt>gIx7P$5J1$r%z8ilFY5Leg%_uHP8FD@7g_HM#0T7Ji(0tZ4X6+Mvt{8!9H-W3|3w}?O7HB0&y8uZOGBE}q*e`v!x zpw0Cd>)k>o;3JL>-2^Lb@2`{t2D}d59Voj-63YPqm>?v5)iUL^GHg1;MYj zy|Z@J?4qgNcQWw%-pzMt*B36T9@RN1I1vjQ!I6of=ttA=4MJVI37=j^;gEY;0dgFSKFK6(ZffJpcKWl0)4h^(NR-)c< zWp$Ao>^C*cAq!(uySmTo8MsYrqjOb$;8RuWig)QW%S>#s0|a01%S{!qn{cash>}v~ zTtHus99BVq(gGjsM6PP{)08XH2lT|33K;h^bSaLi0(CNvEV$`*J~+X5R!asg5K$Jp z=_Iq1lOcU{D!1%JhP6uk0E|i>xL7bztW|QGQEzlcJZRQagj+)(iiW|dZm{B_hhn$mBr^h5#(!>Hd@18#MLJF5-BB^i_)XdRDPOoy z;9mDR!czC^>xlJ&N(JMe_$aJz^5t?tCsVp^12qLuO_X5s>kC4_6<$9c44>s{z`z~r zYUVdFoy?YghfK-`ty@W12~ZIX-8}O)HQ2Z@Al0snNRIK)nL3viD!3bXzbLX%Uc6x^ zEYGGF4#-ev2mcu@Pgwif@jPsN0OAlCRI=g=FCf-97`5F>C5zNS>6zXS^^t@;mp$ta z7!PtcMkO#R8^im_tswR_cVt@(CMv057gIvdtxf)hL_+oTHE3vKyz zMIPCuJGMv**JbFM#sGEoZY#&L z_^shGqzUZ+r{JmQ$Tf|3ppl2Jm(I~dDa4Hcj!3F!w}trBw?T%_Ci!qPr?&Ie7vGyZ zh$BNVTt{pye+F*^c;M98_f+WL3cF+q2>(3-g>v#o2eVOPr%ppUn24lVr+P!+ao zOS;OEdDCo5$=R*0`qlTXph4p!WKBjnK zdow~+bi$>E_Adq*_ljZ|%0xzJ@rn)+OcTJ0&$LmKpA4)wFe)we%P-mc{!ZA{L(%)E zMSm{ld!ASpSjT_%LBRsVizT>=&T%qD7$&jN;AP4!5AvIY=IR94dF#j&sMvh zg4QvI%b{OVfV)^&Uo;^;Go1u)uXuQ!v1j^E2!)o8YA6}~g{WOcMsp5xKUR7x;El&a z5=5h%1KH;Lqonwp5(f9w1>e=}8BI;u){|-YrMsuXmT>MklF&FthTVXgKgV%;arRIm zciO(aMHp<>7Mt}|EaaPyoDZu?O$V40M&ORTvGQss0k47SXr*$I12_t1?Akt=XgNPD zJ-z)bxGqWc+{+*ud?bTOnsZe>QVqKWqI@O_tjs#_E{}3;u4{(Z2 zpMHF|gA8abM9N1i>u6+e6$dT6i(|syrNRyGY;dV{L-Px**H-FXy8zsVB({CtKNy9m zEdaKxJdFK~zZNF!0{?d~%`LDI`Ax^S$edZ0UG!aNkTPEU>mLlNQE>O0Vu7-RyFvyw zE$2ooSAaD51im(R*vYT<1EmV5NTCk3H9H3vC|A*Lbwc{!Gdc>H;2)`knst+W^9-@di^(Jd!FC-+>n5R)z6J7~__h2$*sh803btZGdav;g%E8=<;&VS`BP% z%;)cc){t?fF(|CeN9EJG8jHC)84z8WN?LrZ)kn+58Zsq02t%BlH3^;yo~oBa@w2iu zib7qYW5z(EUz>2ZI~QEHFLK%i8c9W!-sjx#C^uZLu9Wc4J_u^7=D4gIHEM&Cpg$p5 z%Gm5oX|V>v-U;NA7Sp9gR`76!BO_k7dC`zz4qoAFI?datI})KDM!><;;f}ua$Z`xO zrt+tR6H7=xoy!!J@80zZV!2-G7RXqEC3j|{P(hb|_1)LKRSzxdH9X_cjfmmEY7X>R0T=K*ADMGHU2 zd+*gvAn999Oz@KM`GjWiI(y17WYyc+Vg2=jgs}wMVrS85g?4^4e?mc@ccWbgOLv2% zIjphVBc1!rHbBTD-31wYcDhJpWp&T^z9#l_*QoO*{BNa1AnIov_VzVo3ltV@6~u|w zSYmztRP>Z6trk=rhY02087QbQKi=v5_r_5j%Oa3S<9}xN{^QHC+S%O4SeP%`S>#LC zmTOJxhc-ncwRB$ULBrvm7j=3N5v+#2N%7-hh-IdT3}8WBlcQ;hckxD_H76|vx@L+- zqfD3RT@HQndj-4`%1@32(o$MOp)}v8rqDOrk|<6lWJMH3Yy@5JSF8ejzXd|4aKG$n z?mb+F7968TbRo*uiDq+mX0a=-Q=L%G7Y!Csfx@~P;pA}ZZgL17|E`>q<@TEQoIio6 zS7z2?jdd-?0JE;`!*<_+z#Zs{H^#|AaNBdRu}#AgzYd~dSa_2M-8;32KO%=qeAOwp zKnVcuEbtV)N^8<0nQ0%Md|U^sO*`h46CD4YX%uNL;0C5qmzWN7`ICMU6+acT=l$mT zM?#K}IveQN#{(4@TP$FCvmbt>wFPG+;#N=ka(J`Ch-0;rv>yz^MDMt2ybFIV4f$f) zNxPdLX=5B!p~Y?B!Jv6T2-9ReI%(}m7#;mf$oNJ7DyUoLx0q3%W8%9o*yzns zG2Ev6)$m<)MB+VroA@HOe>Lm$=jD9|AW7hs3zdK=@Tut#f9LsIlYj6_px0gg$JyZc zZ$s?QJx5{}N)`WLP8{I=>xO znt0m*KXNcJdm1JB@F1;EaH?z*SvP_7>Wlra(jMN#B;NlVVH2GAKD~4^VK_hzJ8}$& zwv#{_!E)-{LZl8WHc#f@5Hqf@-=;eL2Xjz+_?h}v37BiHFy|SGl$DiF*@(YQSF7yY z@(i3H{fH8JKF~0OUMq)>rX>fl88QOG0pr$7rz3cZD!2>TKaIO?88{zn#FMo_xa&M> zs9vY7jGHu)jO3r;x34-OMoHY-NY5QoMZt}Q2bVc*Yx~`@@y9d4^|fzqhe-Tfes7g0 za-3i{?en(9rhSCL($H`yfeMWfb_&x!7_EH8b>>^Qj;XP6&Ksw4l1$Ew*^O1JoBQiv ziZ(j|1Z8}!_rSdadRQiS;a1a3<#cmS@Kp2=6GwJ!w!BtxnsiRrV1ri-3IQ%pA>&P)2iY&8V$LJ^-yAqYqaeHawj z{kZ)j_Q-tKgW+trhT#{H03u0vW&N4;-n>!OLBf}+^eHt4Tr}R2Tw-Lh&l_*OA)DQZ9q_P4BUARxk%dBCM zd6c%Rc4@fuj<nhmYH_YDTkpS2(cmzwW@pZ zUj|KN4cA^HBm*fY#$w%e&m#DkyT{G7C@K=Q1U`0aZD`}^8Bu-8Kelb@oAXYQE`!}| zeZWMP<{B2^Len>hiu~?jE5bjW2+2Sr8pAo3-&!%Hh?c*_0k5nvd}Edqn869^SqMKG z<)$bY{;`rkPPr{jBUqxKfJ6Xy>qtPipu@XSdL!WA%T&kEWYvV6*%%xZQ{)n4nBAph z3DQ!+Mfz;R@lm7arSMmm-d=3W?nlME9>Y``(?FnI4zJdc=9acDhMBLvJHKI%PHorz z_Q(+)(fZpn zQDXdkCrEE8#`#(&bROkgfS|d|uwgJlhc(VJJy}n$BCbph59vJ8W*K??TvdG~tH~Uh zS+72dAn@}ah31s5XSqPL4#PSYt2)j>)0zg;PMbP#!-UEmv(89cRD|G^nM(54J_k9NhFx*PqbgTx8Jwi6ec0d5(Bx)ugUjqaL{KOHxK;K_z0U6^aibOEwLTU-x;~ zZl~IZgeq2{fwrp;RNt|u!>=(n;)BKfs>_a({CsmW2{Jv$tp}4la)G%R8`L(C*H^hu z@hPyF#^dZJrk@tqsS^{1H%oBa))N015e?;O!_QyjeZ^xI{LX>dhBpIViw*C0Y-B@5 z4NQX(@?RzVc7spl6woy>lHHgy>W{~)OY4M>V@Cn!7m9 zH(9I0HA_@u@>f22ni>Zo&n;5SDRf?GkNAo#U9VJT99+e1X|N-~FnTGDP_oI?GInyT zOSO4*(_>)lM$Y<(VV`g#5^>NOV)$eb@q1Q=?5Midpq>T|6u z#-m7cgSi#vdPeII*_SM1W2lVHeV}m@?zdLq?;_F0WDyI1o(<#%no1stC8nZJS+p^k znvDH%+U-y;x5FaM@n#bleRZ53OGx9cT;~Q>vuu;W_Ry*cK60aO!z)ngV9BU09SH>% zX@k@394uOO(|(||#7&e8+O^xqQN)gN zroc15HpJT3ZFrpj5*Kf9ukmyr!n9J!*lb>bAI;y4b4Jd>{!87Ic@_ zYC2HI_}%&;`@@H+9`~5=sc{;|ZsFR#obH9SttL^$%E7!s&rj(-Ea&L8SS&CQ7{H!Cp2)=MFmjS{*3X?!t_QgtJZ^9O- zh)aBt^&1`u=E^B%Es_(p>$1JgO2;qknkGe^Cl~IYP!Aj?$JumIKA2y!j&^tfy4 zZ0pp8$vV0wYId=M=jl3D^cuJ=uF4fto5WQ3@k6q zjP-xOXE_~wuu`^q3C=^*be4K3NWo>Qw3wk>)~x8@Yd16Xet#H(wH(|2x6aCmPE1J1 zuOITham$-?S|}w;G&UMXsHdl9$lE3LuCSjEB*}Z_04#@Gb6vY5f4!PIB2~mM@2K!P zVi`iArODVA7(}jIEwd{YB9uX0af4l|h z&4WuAYl?$)0y}(YKNB37DCgQZ*UFM&Si%}R8(nKgH8KYcl|pD zu0a(iKJcw>zjB;;Y)0IBh$GRPHRF!ibg_nU?a#1o4JJ1cWuBK+Yt(3UUN&Fubl7S;9P6Sz*4d3d zTwMpII5+oHHKAN4X#Sbq8RtjEi+jwg6^m;d{!QL>lp3_PfUvCeN0dp+6>~gl-SQ&p zgli>`ZL~=rwGBeiCt&-G~%Akpqt>RMX zh>&$EpSO^rKBU9Y6V8a9*zX?<(($x2s-Jmt-c@$+F1f+L9z7GmTLmyf=PmG_u6bI0Dj6>Mt}CM z?8XB--sFAQYKN+8HE5=jkygp3r++~S*mv~)%q}8%{W^P@jllZcEft(mF`Q~R3OQ_u>X`pc;X4O7*F_o=?JBpibs>Z}&X4n$NA5S!nK`zx8CFwk|PHY!fOs`lZ0a zDypn9R(cB|VNH^|SuY*Y9qE#6^!A>{=Lj_ff0JF_5lWMG%9t&lwf{SpH;|<+5N0;= zc$PdrZh=d&dnuDd!=k|{;tNL}v6Y2W^=g=8-ZVwdZmzNEBJ0%@`t1+uh2g^K1j`30JIk zyh;4sNcr(gZsZk5SqbOnCv|!xKx-KHQ15LE;k$XMOQoGO61hDVHRpr<-KIY;e#Vp^ ztBHK860)WB;!{eZ?JgXZfX)v?KLD?TCkaL zn&~>0em6xhp$VB~HzJMdpfRMkGfC3wYpxtREj$gZn!z8+?)o^SiXTHi1ZT6RoDAu? zEKl1yi2JL7KVrEx?K**gQW#4N8Mb33a*{@}fbztW96{$aV0|AiR7-27cHa(SP$I z`mnRRd2tya6pqCEyrSAq(!oI2_tra~0(I^mb8g?MKOyYcE?JuXuexpgKf#ez^?LS{ z5Ly%XRKhk{Be*1(F(yYNVp9vyZ8~X|S7S=9UWZCtdsy8TEX2z6_%$(S^P65ntJ=6{ z7YqC%uhUiw7^(HW{B|udGR1Q?TbMd6v3!v+J>qctoXy}Avc@Q*c0jF(EVvoO3gpA& zz0yaxaKn4ut!vgWu(C$t@)c227g$1$+O51F|j5!@Ki&yTEbtU-F+(d1PV){|NsG9_9TY=w@L@dya{DbUhb(I3v zvl^J;XDBK`{0HS@V>&lAK1uo%5~Or+dud&c8FSHd@5_^B##09_zs7tAQSy{`R1PYZ zdU#hV7$+IqtuSa|2hxm%9Mi|AM(nFnJvQ}dy=>EsqD)z*sY9#p%gHnI;xNmVc%Yq{ z3ashxyS96D#2Pc+Q3r*wPqC0KFIG4=`&rOe}a;!mbzfe#W=*j2YY|Nxu7*(!Y&lF3moqh!xk~@Nudv1gDte>%*<5G+K z#BY>isGxgkbl1PI(qE9JjiP`XVj-RG#_El?F#Dw_g+f*?3uhAHB&E?$c`8)_0xMJU z#&Qlx=JSD2pc6kuzKlhN6mL(}B3*A}sxXRF&P~WB*xOGaWQu6iwN|-Y_wdCgr!6D( ztZsP&){cEH!CyZ+7oE>HMR;qEBjlaC z_PBn9*u(NI_KTrYd}lV5WpGG&|Efj4&%!r|i$lkinY}?5Km2f9pW;(3VH8ahxD^gQ zzlRoqt&UH@&I^jH(F~#s{!MO{d$DHDB8_xpv5GEenL>Q+)9!T-wmH<*iuyDhoR#8qIOUNS%D2>ae;>U^5OVk2Ak27;E{ba zx8gJ}v&sA<_kMw5r-?f*>TUlt{4$=6hX8IPy{H{o5_f#B#w-&mVm*=wjd>R1c_!6^ zYsahAW~IZA-cJ-vldU+zElH9R>?xpb43bwYjE0bhkCmn|3&9TRLtT+ip~Dia(e%7b zOv^dk@4TEpB!!LFw1l?i@C^?zyQoOTvnt|9&Lv@>X$g`Y;Gr?z~WiFl)Vul z1m8i1Qw?r-8R7yxMqughAWp_zE%e7Lo^%Y)yG1FMgd3xg?Yr?Jk_F#3YnCoKA#Ceu zR`T}}hZaX#)51YXA&McHvg9T}h8n?yVN1Nxa$~v=`{#4bVy*2ZO&t!pj}Jz9FlcA` zL{hk3+s|}#WGS83$CVNT-Kp{`usAocnc5iCE!nOriFaNm%5UP0)v3$a;ckY& zdahB7&W&=Q*QEC8kMO?7B3)k0jFD8GEM8$~sx^NiF41S+13SX~qyjRa%|Hqt0_)KA ztwcuNKRc0gy83JQ?Bzvk>Gi)eU#m*`F%=>jSnADd2KNf>(i$2YuwJPoIVtN4qOl=H zkjR+9lIE@dokUWT?%QY4(W3Cnn^L-vcKmkmQ9%9f@sBleD4bh@3WFrgOLR^y64wfT z+%#IARCaK!Ji>ZZn5pQrw+eC2#V*M^R5V|SA2K^t86se(#5{7`_pOY){`~%WO$st% zYbNQwrsy3JaX^|r)a1pxVlHE46S3@_mFJ(x{()VntvvBD)Kdl_rB7ll(W$s(9E`+f zr1|Wf`by0RbP2dg6QAp}j6Z%kQ0NYJX(}sW?5bV!BDyWUl>gjvVnlJL_z+$v87#?G zloFm<8}r=x!-y#qJcphWrQqRX@*;upCfiiehIon;d4(qqSnM5xGUpM?=fFQqovu}@ z)z9>*Y5n0Wo}&+%9gSnlF=-49ib@qX33EWUpk65XMxT1p2Qb=4Jw>S28W37`$JcYf zUTP&fA-hZ;(CtF=VYo>yM-dyWJ95)~qdS-c8|BIozG`K?=JTOk=I+r+UD4>4-jgyN zw&J*f9vEu%hB0NChz|#)R{7PQk9M@n%^y|U6YGo&KwiVb`Di&96*+3?*ks4dL%TSC zcHq43>b3}#kzKa%*rChMpj;z9O6JURsalDM}T@kG17$P5_PQoLB#nC===K~hp>Rb^{Jt8i#j$hxq1m*mhx()i@Gkj z$mJLt`D0LfqpGk(sbkjM3~sA1{sB>Am%>x*{^@2xF zRwYs%+^J^6xaFjwB);;rIVfuuQ(BRt_dYmTL6W1X44+w$<;<2=sxOmW`+09kjD$PJ zBB4qyIhp3-OWo%DsieLi1h!yi^A$iD@=9b6;3QC2qjOYCR-AAh5Rw8SgoKW?CYM_d+ zgSoD%rwglDr-R?#LD%gHk7B4H(Y1J0`9>2j2iB~o9a^De)x9C~V#Bsq^_cM4QEehh1w6GnvNn< zF?GE#k|&+`?7a3fNr4eE4#O`JgDA39sB77nn|I&_%%aB2DU2|?_YUAY zxGz8LIdW7yUk1HDFN{#zXj`cv411tZNJrB-g?m^(Kr7M;^9pdqjGaHe)hp(=isWW0k&F#0QM%491q-bK8h3xiGUU z^w13yN8<{UzH5i~J+3VnREWvnLD&;wx^Eq2U*bO6?QLU>4BtSozdL>23K^)ph^1(i zW=&Kt_4+tz@Mc-kEC*?1Ag3UIXO@raGb%+*wjjV22t zkmrb2jWlYLdV$ID4}&QC*hdg)Ww?M>EWYsv#Sy#y(DaZ>hp&nPUcJq) zmNz?QZSWc2#dy5PR3QGaYueF0wf1=s&duOtLW)13qAW}Ef_DO6Z+h;~@|E`yC1c}* z)MDtmf*|TCIN=9&c$SQuO;$R%JriCeQg$^Kj0W(!3K*la`KoftOfmQij!e|$d-#Mf zJkNVS`Hq~NpTyO-?@Aq}K0#Z?dnQBN&hQLTi1&KYC8I=%1YOTN)@&Z(?EQ*5v#E|f zYHNpnb=ecS<7n=@LZT_`HbXb8o?Gg!4UPUuAhJ1hkCGo@X(CCUg28}c*0CJ{+RHdH zWF+k`euh+Yy)~GeMIw}nv6PlYiJiH+334@4bjL$E$Gvdb;KiaCrb#zd@BNAvto+Rx z_DN)$*$vCi8@O+%6|)k_F1%aJi}LG;n_HL{^Zaxo+c}%%@q&pKYjmfxtc;_Y?T%38 z`X4JR)x#fHjEai2QyVu^W!boDJne7TD02nE=7N+`-Koz|uHNY(e0x?K{(|A{#YJmX z9&{gcf8d^gL}c(DvDmE-{(_OiR5njg0{d)PX=6fmhANujp_%LYaz&ySzQs`HC^K$V zOJkG`=2#)k@p`B}v{D;GnTV*1CX&QAJn}$;?u%jMg}!M?^8(#Lk;uX^PHcC1HB`H? zyiD#Pd5X#^Sx9QJ?%|VmwSQ+7>K|vWX;Edzhrp*$8L#8EX@WHtup3gCXY%4O9`r|B zn&W}UEm;nk{JR4v<@A^>UrP<-1Unp4F*Ck@VUXh0y?E+9K){70vYoGd^=rb2juHb|_5=%ch>CzA}IeXFuyqdPV0+p)WOtjFE`l2 z7o0eZENAsqhpEQH+oQj2 zoX>rS9TZH++#FAGksYT_Vx`BeK)xgsH%e3Vm?u1S)vVx2-{JLl(7a)*mXp?N=J`Zn z=(=76v)ZqFNHln5=4Lth>dRzljK|OVi-n}F+Hr-Gd88f(&zEnJIkcfLH$^z;$6jIF zD4H=F!FMFx$<2o5nk{;@RvK5DjX+EB6G{O8;yHDk%@zcZ`sk=z99MQiz^Up(W+qSx z3`>@D1rlfHGkczkA?Ng*!4z^lv-|w;u_}_U@dTM6eB+dVp7M zZ(@F)K6-mn)ooF?aD7@_X?|kcm*=RXNBay0t&)_3L3d7piap^ut}-b*68tMlk{*P3 z^m3&%1Ae(N_`c(3&^zr4sZbys7%I5WiD@=qKB%WxU!cRTf~#|{75KnCnmP5YgEvJy zGn-ks-EytnU!QtIxm=1#TajI0#UC-Obc|Xs$pVbOX zDi#K}b(42&ddGYC9X+P?-xX=w_sQjT`>bd0*M#WQyh7i!NTzQ*q3S>}S51KqoF2d* z%+zL$A$}?JrK((SK*V^C+BQY({qlb9Q@v)KApRICdUu6E`^&Kogs7b>`t%#{Ti4HnPSJtvs^qN>^`S*5$;w@*A=Ey&61U)| zba91Ttw~WIs~qE%GrQ>?qqGx`)OrM7^$zM@^~YG&$y;)` zu}`_2E;qPQtP+1CcV8;o{OrS0s>;Eh$Ysz?w~=Hg2$Qblh*l(d_2o5L;Y1jWr8v5JagJ z7dzdE4!tRBeUM}r+;xZQb=op`4HVrCn9r8^fUPYfQW%$toXhP@Q{`d8+2hmTLA6$x zsyLLdDcI=uMa0B8ad1kw4FVL+1 zo!EJQP4k~I>HnHBX}ltbrWBFxW3^Q&_ec~~R@zr>t^ebUP3-=Sq zXC7LO;)-3WIb%6w&s9_2B>^Y)+w+94-$6`zU_P_x{mC?&qQ`{FmE!7?P0V^&k(%0^7Yd^ua5$N&Zh+l9(eudvdROGMdZug>()Y-+^Gh@qJo_B+xF=eop*E%Y^ zPMWg)_2@c;^OB!nXB8y$Lhh?b9Rb z9k^Aw%TNiz)+@c%r9RE)7G#*(6(KF_lw->U4S6)8Zk=j;^VQEvw80>_vcxUE8x6Fa z9Ro<9N3U@7iU-@P7WRBT18WM<}`fRj^;aoCJ9OUHa zcls?@Ao zv1|Q%kgDm^$ijGu8kS`}{aJ>uX^q4sbuSt|EmnGj_!^GdrAQ6<@5CJFMYiZj$u`<1 zrVV}NFFc19E8p!|8M$CV%1PNrO|bQnV0=D)LgM8PnUPs&79$WN(aRVo!G56pdY`&o zzlEKboY4aRQ#fhbo=I=3waf?iw024bT!_y+;-~YmCyttW9_%X?>bP*K;pAnx=C9@Y zV*}rh;mI4IeCCjegx#=oRn)bEfiJT~Xc=v)j1yDaiz-!_(>|n;g?O-T3s8IxhwZE0 z#>q^Ufe7-nV_7trO*a0|qJjMuI_y7VtN*`_t?H-d+euw3Aa$f#O=uN6W{m65&>iJX z)ziF;;D!llyFk7cFP^kpBcr;W0_wxMwv)uExA9KVUq{l$TjrgtgX~ym2j*0p-q%}4 zp@v9^F)p-BGjJjX!fM*sKZ+`Xm5`Iy4VtN|HeFt7n5zh~i5DF|hNXgLtKmrCWXD=1 zH??x5AV`QYjQUuUkw%zW`X=Zady1gmV7d@DdYM9}p^g%4&J=E!oU`(DWMH6yNxWID z;R6n~dlLa=rXoRM(oI%ItMygA9ZsPze&LrYE9q*(!-^j{*fE4=2InR(Vz-b|>$l&n<-sel z5*)yflrp79Mj@1r$g)l|`EvQU$k~q6e%7rL5pwi&u&xdC0j4R2dG~kSltot3pIYis z1|6Q3)oAqLQ*u-r(-SAAhXWdo;SaNgjct807c>)DF>UGAQxS{D9r$V(xq_I4)C zi6iR|5Q2RCy9~=(o*3|jn%r>HY+Frw*OWshO*Cg_Y4Iu3#&Tx4vr3V_1JdWFZtSB< zeQm!vCdYNwAbsB6@)I9OIXK1!-{D4|$fuCHhW`mF^a=6{L=Zr**OV8Ut^&bP{_PoNIr{paahzQ4e`K-kj z>!f{nCu}q=Mq#$Jj*XWl(TBg%6#DFZi-t5`Sm#62t%vf26T?zg{LpEcV5zKmLer7e zb)})}&XuVYUvzqFY_as(;3&c~`9b-*$<3S&Hr9Pl&9&W{roMxW zaiz~A=IAeycYK!{CDU0ATn2{};;BnI4pe8dzDOHLHT$sEBM`)jqrad2!0U9y;-AHq zmo~-h*2J0BIDfTFin0-K+qwg_LTjdzG_4fA|gx`ZVmh}Ue zK3ta@$VIIRQ&{R8Gjc2@f#2Gvd2*afiVR^Y#QKjEzLo}AKMzEqd@6k+p>0|_Urzae z2Y3M&<_r~xt)Qb2SECSM{1Q8m5@u7pFAvdrnUvw9t$?=I4NfJMi^%k2PQfV;^J4MU z2Qs%)j3XYC@;PcgPCxFhlhM{1?v$%i zkn57G)nu1oikFjXuT&qBlF&fjY_Duo6T3AIR~+SWur!_Z6g&KWRjiHQ!iE?%{?}IXaV*k zN*F9_lqva;XyIrV^&rOV+a@DV1g_B=93iTW5ysf)O#Bdn(s+kv3~DV)tkb?o3S*4G z_z_m}vQM91%RgAw2UoDz)i^*qLR;7|+9$&LKWcl3{-ywt;rb+NuSur43bR{I?`weK zdDPA1ezBbHV?-l892k!P7DD86V$&X~LW|r9qwb1|*TZRH`~72^{A9HhX7W@EoyV1! z^#g-jNwks+di{Jy( zYX`3;LwRO|ZLTOx+n$3rnIQsCgP(fBef76^Jby0LZnK;I@BG*Lmo&Dm4}poFT(!gq zpu%^xrbVxl3u+w;ai4j2f$ccSOQ2xby=?T(zg=OgE!y!w^KiowJ4F!MXnxZDRNr|w zkui`zI+_LoPedJZKJ;9(&g$&P`M`cQlWedMU4g&7aBCkWX3Upy&LP^9HK3Ig^>W4D zxv{I&`=OjJ-*J2HNfXmSyVrpqp%z1FG~Toy_a-e}#S=Tq#g#Rec#5ndI)_cqh--yG zU{=n@Dupw+PX$+kwaA-1#wxx;B@R(fq6W@g1Xdnq%c!Xfw+$Nvm-kk3+@TFDmF1LO z5BjaxUA)?0ZQC054ZGrUCbZP3#qCMgrF0z-AnYw>2!|yYcIXH{YB&o@JrGzdGl736 z@mzJqz$ppU9G%nrUEBFc`;#sx$Bwj1yc7aKlGtuOS^7$KDiS!N?1h_QttfbA z{uAD}3%NI?b?l!=JBwkx3yv7Yx`rzOiQwtqk7(EHHfyl^Un0AjVDX(3|?la zi-Qfa^cF#Tic9_SA}OOBtE%m(jY(pVi~;6viH!ZQ+qoapKev30$Dyt#w#G7nv(^a$A_g8jK6N>02p1{enoL& z6eBXa89z5*HwG%5#mrPk`5Dvd${}cZ;i^8H8aVor5AoWxg|kx+=^GSu2GM0J&QOc0wK)ee%&zWruuCIv3^(e0f$-TxkvSW zQZ;G$0=m!ID0Watp`_$BzS4M@4h&@uqVaLXp%`C2iZLm#8=!cLm!ix6_`*BMRIhFE z5k-~PfNZfVh>+2oIf5tZm^nhu^xa(4VMC>(ZITt~q?slhn-n{Hml%0Cb#JQNdcOCH zMV)gA{k1%eedy7*ZH$;3dD}Hd-&8jTbciXHU3yRyB!}hdwU2zDodjA=eX#u9X0uHM zJ)xCELa$j3S{c$(#AzLOJ$PqX(_vevDWddYQDlF~$Q+LL>W-FRt01@CC^DP_tO?`p zn@u*|L?eahV#(0(Vxu0Ti| zCo3p{fOH2Y#K`=LC!|remClz^5`~T7G!4*3CMYqo`MA3RzTsfsAdv)YY|)MbJWThU zIvJ+?KAw5|4UN-=z)JI3llA%}NF5|wg_AM^C)dBiUn*RMTxgOj|^jFge2X(l>78zhS#J&Mbw+l3xzrIxZ*YTN6!iHioR^CfU z@*{z$ob4aI6jzyl{lP+K`uR+s-EMMJH%meSDt1_q`(ws5D6Yg9A4n4HO}-AodNnmy zCYeq{g3kD41=_F`KM)UoJ)6fHW=QdR(@#A_AGgu8B1TJ>2<>$- z@y?Vt;x2tM=KoRL#m0Y*yNHECIuDAg7@;L^+GzkIR1?yl6JAd!HXoGvKlM?X`4l6a zrTSh@o;tbtsqn1r=}Xp8Z1z6;*)cx>p*tb%N6>}>21ymviB|MwQ;@`ENte5$OS8@D z-R~gSJM|MX$_9U$2){8qIa*XBh^nB}^wg2Y^-)8gvQqn)($WPh%Ftyab!BUYoxBv) zGG%X8Q|vcTo^XXyt#m^*)9(8+@YIuo7$Gt92pY*f-I#)-Ac2qE?ZbYle0@&{JU_pZ zZ4VfBJNpodJ04+|RhxNO)jhuO#R%m)D0=O!^_^so4}1VFeUI8Gq;ByFq7Z`p#e4#< zWxI&4?~~y8RD;uFx_OSZ;qJlXO|N6^WeJ}LGp50ZY*OX}W{zs?4a(XFr1kUG2i50z zi;&QAyJ>q08|{zRwnKO=B`C)J$WuI2Rbq6iU0(lwHvZR##-d~cfKMD|hy2ELs66q_F@t}&`pJZ=o?vpkdOI42AONPNuF)Z;_~ z&W_+<;Xtatzbv7a0`YMSK@$c=qESPkuS`yn6kQV1;ecCtP76%&wXUsjq4K*@>1$Hd z&pBQgVjA!5=C}$yqYYF;&uRqOv!13T!dA4QliyiNmqj3c&5o`nteMSo77B;sI7S6w%)|v;L@qvZ>edke-*DXv25m3HwOr zOPxM{R#E-VXJ@om`v0n$QZ#nbV!T-naC{q?F)>=J%Wp_hoPJ5cgYW=v$G%c&p-_DI2u2xyeq9@4gMS* zP1|^6XUWk|SwFaBaI*kqeDd)fqSWE-eoflhtRFx9o((KQ-kOP)sFwQv5XZ!O#1I&8Pa&7njgx8ag@RBMDu zW)XS>)7Cj^Mwk|jUbxGvEV`xVZh^TeHI8TQp~oh+TAlpV1XdOmlUO=6xKSa@VieBk zInu~zK6$Se8s3X2&jScYut(B6$ZS2qvdu8+yys(2^vOCJ3vEVU?FLWsrle?_b~!K( zUyr|m;dbnh)+5C4AlF8o<`wm9B>mVnf?c+Ejj#h>6wFfkLFn5GI?wvzlBB6nR#uc` z)sokOJHtlR&r}{xi`Ks=dXQ75qnpGQad#}s9>`Ri`jX|LAlJFH;O)#}!Z30hMA?@3j+qU-Ma(X9a@CVYw1bQ(V;nh$^1h z@TkR9aHx90|0JBu#^Yjqt?9PC|HHrxj-1CDn+?XKD~riKzr)c|vG#J8LDIBnbG!%4 z?F+WKk$7uK@?bcX(DxrpI}Nya=8=!8TF1FQlPa<06e$_UVT6bzwW+;MVVjN$g7jJ_8D~x5q}Q9RXfNi4*e1HeRNJ48xd_qmki9jGbw- zS$2cB1>9B4Ak+2`9&@JS6lLo3^al|J<$7XncoDe#b3u=THN=;B9!DYX*F;ay^K5UW zuP?(SL2^c_z1ez?lF>6H*K@U$y!ynp#@v@}d_4wq>P589@zs99*SIxO<& z!pnUvw`_ba#aG^^gR(HE%h9YFd$|$c^8(RAs%>DdHud-^4~EBzMIpPf4I#)wP!`yz zmn#b#RK5VW3>#Uzz9$6TT~aHQoc+9piM;*d%icVd2||!8KZBjZ3LLMM!P>jt;Fu_; zfwiS+?p!OWfkE_&kDQD$jbZPnOQfD!Nj>%IMk?Qo-%6EviRZZ$oHRC-an7!-FT^1K zRQ)7P;*&3NPo45xuv)cS#V9k*UP5JV{f^v(C3ax`2?r|U0X8?S z`6)kZ-8`2fefKF?x>>H+2chsv%7kT*5+$6S9-;o~rpD=2=2_Tq@o-{2G!*jJ3Y!xK zn~YLm*BT=dN~m^vr7)Yv$SsGaU;HUP*`=T~+U0*5-QsY=tI0}cAeqs~dn<#J#Lnj>Q?*-=`roGoq$ zEFIr6EOUn-7~Z-Y1u=fPJ~(-O$KS^Ik?2_`dZ~;~QX3oW3DL%$m~uR8To=kMs&z)W zfbBVJC)2W^h<;Ad>ZZ)TT1WhCjg#>Yp+)(%$qno-3Lu-7bIo?m{; z-D0Ze{%m%vy_6EfF#0OG4)V$DU7xmOiMlQtl1KU} zL)|QmC*_1S^ZW}61=(lT_B`dbV^!_8HDF+e!~&ci`n;63TY-WEn}h0=_eRA;HqkEC z@73>2Uk$K-2Q@Z-1D3DG1kBHZ8F;WJbkfq!!q4yG-w8LkN1K!cmO~&xd_i+mSVOVa z1mWSkhMUU{tq)o{ttt-AzbgJuUlDM>B~0!M3`@>bwiqYxl`59ob$v@V>=hor(5wao z2U^aG4pYNd3~HNB&Q8tqZO)k9&Zs^b+qV>{%}jMfAC{1gR!wsa!oaAs)qdWaxX@q5FB4DypMWV{*|k zC3sG1TC~(O!IW?k`+8m^@@y8Z;ACIP%eW0R6vX-p%7s;7#TDuOukYALETzU^rL9O# z6BQ~stwprm=?hSz5?g4LmgzP3BXWQ$1;CD4@QB(ty9cm@+P9 zU1W|kAkR$3HPYJnL=m}Of+fzp9!=;=_#PqnPUAcVk)V}gc@W}Q2M?`?^?u_G_p10n zVm|I-rp@P&K2f8Eo>?c03hZ3GruC)HXBjz)Ol&|E2O+9Njn#SlqpU>S7Si2M`LyngG%5-RPkg)cYtBzhMER!^pYNS3pm#F#^w@TygdXruaqx$9{9>$~eKhQNV( z4g+@N@I>G5pbbO{Dni=3HxVF?=n-Bl%9vnIlI)j|VSM~a>{HON4tbtr&k!XclEx=z zXAv_hsu4svo)s%6<|C6+<%^npGhRPFUo)X~5}7aYC}pV{wI;pq7{7Q@&myKBAj9}T znR_)#uiQHDI3HefqN>F>UTs~V8OR_{Fonvz4vhTlRV2|h2pW3%o*=^b)RKujaDmQp zx^ZQ_%!}AiFp6n5!yy&V;Sq0Y%mykHCKUdgA<<_&+v1owIGnAp4}{;|&W>d1ugdG{ zey)%!-c+n)!r-G9 zWo?8s;pe1B&wxeI-|{tQs;DJm7#CAX;>LOO6&h5|EMaE|QoSd+ikLIk-&kkP*kBGn zq>dEek4+8C4s$(WG-Uqf!L9lLZB`Y}eVN#<$>r7FyH^J1dJJ{&%@PtrNis>Q18roc^9Fwz z(Ef3P@Za514P9YoaZ%9A75_llaU5#w%Z&IU^vpKs-8OW>6niPlj{XMie#!A_>at(= za#8EJ+g<9ZwmlR_Yej$ylth3}M6|KQ+Tet=+}Yvj)Kp`)NJCObIaJw!s%!Ra%`hm8 zTKnx;X4Kitkj9{PQXtl|7N^NInM=bh+vxexe(;$?qO_|LXJmA6_4x6aX$}^jdH&3i>qhPgf9msN&9o!dH37w66!XV>0$xU0r9lCh1TOARfw`4T(c2s-UU?FV7V& z1S{8$j?7PaJL(XL_o}j)!@8m$xtF-_-W;SuzljG=&1f9$Ny#uI`Hvmn0jp=}QTua4 z3LK{C*ag|D)yk#4b&ZZ{-ugkRHv^m zD6{`!=lpZdodM5db-a}&aox>Hc%~L{OR-Kl<;|d>Cr)0diEQCn2sKFGFyFQ9TL_5? z=G&y71XNHmkF|NdiZ0b=@aJE(M6pZJL>5!xD&xfd@iC+_Iw5R6-@)BZ@_OH{)pOB+122>O1u-FvFnM{hnZ34b+Y2x* zCb02QsUoDkF-@Ds!Bv*cT{cqLM5>{=^SCgjqJF7&TTNr6vZ-F~%fj$88f81TjE@(@ zWz}@+0l7Ly3^uzLV^B)oG4QHM`@W58^<1yLLT>0jy`nBcUi`dft~s$y?lVFvDx(-Q zK_vr2G<`&(R(-lb$Jrmi_v%U>`-Gv8i7_%h%(wT_BQ>Y`d1X{t{1H0-QfeAOq;x2 zyO!`$Aiw1BqTFXsnr;navF4xHSJ9!t9QCsQQg`TD9<6uSe9A?#?OxX~*S|HDcp_+z z6d1%YcIV8L-OEP1p?Hm4V=-XNgbBrlohtCU(tY1RasY-!yAM(Xhbab3%I3?14Ij2n z!AY$Nvcj=Z_!c$dWA`$tO(z+yQ3ofrq#R$k#h!!IrR9TGC@tqP#L7_H3q~-hZ4KiU zCPrYHA!NqlS|t+MMo1ld_X!cBGQr|V^!jN*Rikg_pMPR>J5^r=oZWR#>#P|DT)C2c2c4CF2elFeTw#0%^#$BK5xyS$4x0N8x{AFWoIT>` z3%KhC63qo{lid#9kpbJ?1K}@$Sv^45HoeE)x48j##TUwV!Z+Ekw!VXAuLBHhv^vdn zvws;%?JrXve(}<|`}-p3KcD|kHDC$L4#EaOfl#0@KnNf>fcHJYf)Ii4RDiPo1@XXx zK>vz7p+TU3MZd%V^8WJPzrp)|nzsZf??3Y3|Ka=}*Zz8J`8U%1HIFqE2qXj0U$6gf z{9Oa{Qx6K&k*4$w0w6$RNQw z0^|meJ3zo~kQ`8D$KRoWBP!-SN)wBfMvre zSck$b09p<$$blM)6vT}fC@%L95Eve$0!XC_9Q6?c4S`b=;IcLd`Ukc)2$cZum)INt zHX0xS4j|`GY$(ug$V7jSOa#&d!Tdnh1d#E6iOdNgrBTc>rt-AmvY8{M0iXh~_t`|CzyWg8#-t0q|${JQM&P zM8D+03-CY!QvO7T2ekYbh5QDp1bD=IG$jCy_?KvWKhO|=Lqqt{hH?MYAbz$pT%esH z{lL3#XAggg$NvKl={Gz?5aqpeBH?gA*Z4E+Z&I27mnA@=#wXu%fg|dDhXOvBK&d2v z-eC#!4-cTHxdXjJ1vqyF$m++pGsqgaCI$3HN8s-LM-Avlr{C*=BPz*{3m`UlRFDRc z!xTWU08;+=QxB$#G*Bnr>$T0RlPvC$nCij=2K_~zSJ;;vy?E4$w2y~twA2xV| zA2{SdE!lwFe(;9=VFy4UeUOmIy~g!{UXJ-gLpeZ;)Bw`C|B&F`?qC3I;|riiT60(^ z5R}Tm{ix+TEYNX)p8gQ@Q&C)hqkk^ITHImefuNvd0B#t+p(FnRog5?%=;U5U_k8|4 zBoUAfAOSX%2nZDo`v=m!rX&DengQB&0CaV)Q*w|ZfaVOKL4&XWp5k(tAVWC>z~*2A zdcT*20!j*m3WfC>0@g1P{wUd>anyd`utNcL21s;oW8*;Re`6Q_i14rMp#Ufgz!HNJ z_}y+}f{=f!Gj*UmCO|2FTHJg4jr&`D-1nyYHgsPu)gSUe|56?fKsW!T>wjfM<$hqA zKmmRPu#&$jBj=wme`PsUeqgyksQ_58zr^DD6V`ukGc|r721027h;Y9|oSX{tb{z^{1KVjW_ z`9GVoe^^M(A82o&0DlSC%3q=J{|W8iv5#uN806lr0KEj0^apMYAgwykS51L_`d`)s z9z+7zU2W*!Fwp=(3I1eCez&;|zMP#Hl$WXJEvP>jF# zJ!2?%0M#9^O81u93g~0-_udc~zo>w;fwWN2KwJK8d?f;f2$BTs&%JFo0c`8NeZ9BA zKYhMPIP(3l2PlKf2r_W}`%iKm`C&qVAAtR-7Xj=VG~h>mLnMbr|J_diod>x$>l7f2 zkV$AmfB+Nx1Em2#fdd?*F#r-60trm0VE}o4>hq^Ae|i;F=zFh1{Tom0 z|Ayxu<^D6$BM>ab$#)azN55;I4R}KTM=Sm5f&aO7|50`!5FC)(1zPC$+$vC*|0KuX z<^S259)aM2{DFVq{sqYYXYOi%{wx7<1;`Qb0{3+Z0}?`IP zQ(>Bpr#*#K#ct)G6C|E$e1I5Qhno9sm6V@-`^?Zj&&aL<6HHfehLmVHKd-g(8JCSA ztw`fTHvc1nMEh8(f)xa69~-}ifjdNkIIsOh!gibJKS!PS$z&e)O?q50qDai=JP96R zWs4lF$@%i_3YGdKIdA~xaroRKdy~X@Pmc7u$VBy#zF#tc7vntoeSR4f+6U zO5$bWgJtDGc;t4(kbwDS8vX$QiRD*XUVI6ss6l}Ilb4ysa)H~x!EXrm`CmUO?=5GJC zpmshf_`yH{BLTX9C*W>v;b6h~hi^p_M-wXx*ZanSI;M!+OO7eB;g{Y!Ei$~&YJ9yo2nnxY+Pt%<9qVCMy6ScBk+5}R%+YFFQm2hr@u06N**xLB17~2 zz3?fGm76KR%OVwG5b(J4H^Q^ui~UJQ*=d;vw;N-@i`?DGjLwq?!6R~^HiKD_xX&?+ z)FvWjK_yS*ova`6($+Jm-Zqmkyak6a6TLwEg~D%Kivso}lhrlSY6<sou{JVe4Y$k>l^-evhklHB~ulmd)iZNps#S!2gB$tb*zNM{DjOT_&Fdz)5GJ%dPg z#Yai&1VgJtv8BqBDv4)2uK%aK^8kzDTKo86snTuOP*+sM0!S56q_`+Z5djetqbn>$ zw;;u?L4%bTu{SJ1V{8bqcSQ|$#a?0*4H_E>Mq`O0-~XN2)rG)S<9)vGx!>Kx^V>6X z=G1r2oH_3)!yOO3yy&); z5dE}a@roT=ho{xbi_cutKY#nyO^ONEc1yjJ@};9@B!zd(ebFSh{Q%wZ+JlESyYlGI z-TTIPpJn;Kf3+rJf#c~OU*_ICp18p4`S9fJgu-N3-oqoTTmAB8mG$pgs%4z3H2Ak$Kz5aXr zMWbVjwv_gI+4$gQ<3eAZ4Gbzl4Hh9Vk6J#tV`@wcy+4HZ+Awu zvbk(r=3ek!qb?;UceOZeu{R`Z{Cb{F+U$~eJ0a>#hd4k zk7wp}D=*)Jx!|CQJtZ%*3Pm|fOAJb%Hmv6qF}!t~mc#egKWuQ}j~S<1&2uYQ5};eY ze1_$-({1AxkF@OUeq>v5Q?0wJ3`dPmK3jVfKGT>}KYL`(RjuEW&$vg2_ZRnk+HUb^ zH~&LJ?+pnpER7i#`Qx6>8rVL_adpc!OX4!OCmK&!9Pz;T?Fi|XvHEFl8_ti(wA}4?%>)?N9O`y-OJZxi78OnP-ghS3)PMMpUM)wRdbs;5 zBVE^FS;Y@quFvt#2usL+wA{MRiLX;_`kZKO`S?^)YuU`H)&sA_h{KvUlzL=Emi}?j zH1GcHH_;(k4ts(UOjmSXRX?bBVNKFbyl_<34fuVsgGLmG{9%WG_G zaXCXz$NMKi#21sF?us+fuY1aGWvTqd%^S9bMhzZVHM*T1+wJ_Av#;06v*#V1v8z`4 z)pcdFyOk^(vaQaJ1=g?iZk)NZ+Hp^zV8pH$H;)92);YU(_0#7f_sy%bvpabAl;vHD zmXA4h6#qT=@M4Q*ztr1nmv(k)ltF{;`|G$q?j002_pXy-d-9JrTCF|oGI`tU>_fp# z{U(PGi0t9&d@9^R(BWM6#y2N}IzIAkJGf=J%j(FeuLi%ovYK_-y{Yvt4o~`CyY^je zS(n#K=7)CcBQnk@Hkf%;^f)HzfN9^NHY@9FvJUhuvQL_|CReuR#+~fe17AHqQT*5~ zE-_S(rrKSdAiw^ zor0Fj@?^7&>JMM*lPD_RpI%sS(R7-{&dkY)2JLnRx>o3RzE~kU6V=!{_x8c>pC?Y! znOyGYJ1NVMn}R&Pq-EAK+L!g1%@eVKM=)!5?u zwmWaF=-4`_V?n3Z6Tkh_a#7dxk{y<(&(A!7_tf9}8z$$nR&2+WCU{A=sq!Y{`ySjY zS?y)4?27~$9_m;x>1#KpwbvsItRr6!v?7}!k}?_Zp_ zXW_Erbz>ZFIwY)bY~cQ2{_rIQvYn5=@d~vFo_?)MZ2sU$-zYkj){mbZU=w8BD%8f# zVNtSan_hFXi)MtsO5fzRYF0#v)v7h#$MzKYy+|9s^2t)IaX+@&H^hAGCDv#`$dZaJ z*TRQpNIEu~Z?Kcvy{=q*!@&GcoKcc8`%J2Z@t}h(Mm=F7~iWNKH+0 zx3^D;L03_nVy8%w$Z;)Bkt`FZ;xswlJ~mlA5)sR!_KqDpy4uUciE=A^k_TJ#rKt{9 z!qibXiXDcdA@Ppn=16WhiXDa{aZC(!68KOas9bQJcX{W>N#)|C^5d*>aaOsws9aoB zF0LvUS1VzHG*LbbB_hj87^jf>@eZmZEBkIFy+=@{pam?T;|dtEF+z?C%tLA@joTBZ z0Anwhpl7J!e7}??Nzp~cEF5Dw=&0UliAj3QJ4A>uAsWuug8__9ior2PhaO?PnWhlB z0!rKq_yBmt&=6xifj^+Qme*%2#R_?{XKb|>V=sC$riezG(Ccp?9*WByUb_Gf;0e4z zchCd)fnMMzgxBfFSaVS7$XFxHXmtYh5RV6l1SEsHk@YI-f6e`7aKGthnDO;O43I;a z5WfP5fFy%DUkOx14D3*8nmsXx&C9TYrKhK}7bGw|C~IV9pz2(~`6b*MqEkN}l6VwwPr#i4 z0iYj908_yAVx&>S2SW8Z?epj7~4Gr?w%7Kn!t+zUk=4MYCGPrwh)k^*Ss z8E6i=55hAAtOr9!1R^nGa&QjPA}%Po2%ESJu7GRcI=BIT1`hy9SeILFLrZS{Z_q)y zI(V*ln~r$|uzQd8F<)bKsCR`~)jxCgI=E$nx6kHOd#zUNxc29*4qdGps=~~ixwP%+ zP}8+||9zsy#YHo#3pam2N{83?DWa`6>hNx?2 zEP6}B)PrI7?xlrw09s68!#x;yH2mm!-BHFxlEnw4UsWWHxJXv&@{z36r56v^C_kHp;cGmBJg z&PP;i{uxEeuggc0U-vVLly1RCl5X*tMG9%eM-I8CEc-rm)nu z1y+2KL2X-Lg?dc;y{ou+PR+6{V()%+gR zv>R31jhZ#Aa;1h<{y7@fX{CmB`g1j`Wl9Ze+2?3jGNpzk`y36+L#bhTe6EINQkz#t zOlp5v9jT_<&37$-R%%#3e~yNgtJJV^KUc#Vuhg){|7#6P9}g)F3&473XvpH-2@Yr| zLj9bEAKssvXw#6x`*RHEU?@TToQ65n&uOT(W}wgn}yZ&QXcZ@HA^G?%l3CJJ`RB$@5DNaof|wGJK06kSF$*KX$NDzN=hpL;HrvkHwm-n8ITW%(?N2aA zhcm2eR1wSUdY-*ZxXSX4Z!$~c+ia)xeU@%f%F07anZl`z&67Q0vbN8dSFdMSKUU7x zG<(a*Ks9toC-m~E@X|`x;)Zi+NSCGiaAU~aF-}#sKvmaiBt4Rblf7shoFdR?eX$&G z7*Md0_$610No9Cn{HVD=HFjP>BkcS*x*)|uLl3E`Zsiib-G z4zvW17PzP2axm9ES-MBu=q@d<+lnf zK4Z+uj!WH0Pe(we#?-yBSS=ALQJ5~KTuKy~y7^m5{kX+#@$a??rNFnZhnfP4^H~Dq zil$kVrn%A%#G+MN>>i6WX?Yzj!A;@vj6rtRiO;o}E@fF;p!2(ctsE<)`@)+QO1nFk z<3yB}a*uGltaWrDYdvK+3`=_{y)*T2BqP4eknKAuA)pQ?B{9ON-6Jh73fi)fpu8uT zlHkfJ(ATad5at#>R()>y%@3)_2gCAR9p+## ztsyHb!q5XhIA*_kgSFqVlQpzaJ}smAWf+x3aBl;>0=~D~HL(?IJ$M;1(;5j^kH-=sp>+H?#n+dSl=hLKkY4 zRhVfRw8C)--Who9epwUr`k<*(OaN75TF@J(iZRC=6HU(XW)v(!WmaOws-mKf^3(#e znsUsR3c1D0v^|Mh8!3KiqX0esLd>D2aczPG3)yLLdG)^H-}w?^(KKy(q-Dqyx7E8e z02lPZsN->APm*OMSra9#v@K5b7wZ^nenl>MaYjjtYSlzb4351Dv2pQT$WQ_L$ zZM2~cGPI?IHlP@DS2aKXFC_4`0#lKANmn&ma44R<;*VFo6U;ZvHel`BY`I45gE73) z<3ZOK0SdVi&_w+~Ku=r=z;nc20;*255rnD~HTDLu$HAsYkY2kKS2k?wcI<_11e;y} zRLL&Frj3HduxTm8W7v2vuxGH%VZVW07q$*ELHVG@q8aRlz)vm``pdBjMJg4iVx5Yx zXIf$`-qUm)EdZ-@EuOAn$wsme!FWHEevf3aJVofENRx@VaIKW_1_t^B_LRtlA<2pw z)94Dn>x5wnX&R-TA{0qd6658D%JnWIM~<|UN{2|}C33qMg-qQ!CDsnzRW3csLoh9c zk=n&7Qf2Sls^$yDW{z&}%N~>%ldMQl#H9**$HgVaNQC_q$+7U`1z7&YEuN}lzavZc z8z0r;+zo%*vsrbVQ1Cjd{&6k3r<4b>>D5a%y_Ct;7>xup63|FMBLR&BG!oEAKqCQ- z1T+%RNI)Zj|11gAr2msXEx2_0QnpP9=x;P*`5f(SZOFDWI z`2}AC8UvUIu=<;21DaS{4M^AD2uPRT3P_jV3urm{5kR{CDL`@m4%Bu0dN{ADUBijf zO=)15bW|ETCYuH^d7agmOA}5t+Rcy|DhK7UhA{;C90p~Dh7zb~;fbkI36}r`gqa6h zr6UV*PR>xzxj9*96RHbU{VMQE}qF;%=|lYEj++m)Qv4Qwb z5!ou}ih5d9=ub?ri}XyIucx_sny06^dD7KMUnQNK=Hf}m zC%v6?deT!#cPE`3JG&*85-wICNNi#~sk3UPs^roB`?l*!9gi0n)j#^ZVUr3usQBK3&iacmglr z4SYa%AOgOi2j~g>fIsL30>E3WLJEQ%40?kQ&)QN9Eb-Pw&0cs4uw4oNP!HtOBdScVG?p9;^lHz;`f4ud1$M^Ffkf@9z~H~~(AQ{Xf>1I~gXa1NXY z7r;eu30wwOz*TS!Tn9ga8{lVf6WjvD;5N7eegP%mF1QDN1^2-N@DMx#k3lK;4g3zu zz!UHXcnY3@Kf!bG0=xvTz+d1scmvA8TTlUL;71DxfHuGab*u%#^AGfa0jLEGfe|nU zCcqS!0UGzK4eEfppdP3XEIAYhVr902|O2 zv;*|moGjIo8Kv&=ax&cq%1-yX|=nh1{7xVx< zfgkV(_%Z+s05m2S1cE_t5CZyuP!I-aEVM6(0R2EDhywk=01yoZf-k@zFc^rz5D)`m zfds^Xc#r@R!B8*^NP!HR)}^T7hJ5G(?V!4g2%vtcg-%fSk; z5_}7C09`My!dkemQ(mL%8?9r>sCe zpAL9ytNy3K$Aqow#}vIMDvl}-Rj*ffo`L`_-S{j0xY6-g$f5H83#cw!b#9GOenVW) z1s_{}ipQB=(lEN{xzIvkS}IKUo|Z843zW%4wal6KTivhCKal@i5|}w3o9^FA{%QGf zL;5<1>Qm&uR4x4=ZVQL17SgxXX|_UAT~VubYmB?EN?X5LA9&C2-^JDY{J|$UTix4r z^g4XO3G@^L(R1jB<3r3Fea|cC+d81%Z~-$iq4@Pi-_=7sD0l3LH@GT&gTGzn9sX7N z{wT48>s8he_yf+W=dTw0eMuuY^)y>h?+0Dh< z)~%yM58FX%QNfgSi%}3n^EwnD$Xb|a1s@ivKgBYsa%OLFB$rfJ&brPy- jAU8x66h`|T;KcPU=-5tm-Oi0Y>%4jRN9E|h%hUe=15}RO literal 0 HcmV?d00001 diff --git a/GUI/ActiveThreads.aspx b/GUI/ActiveThreads.aspx new file mode 100644 index 0000000..134a9b5 --- /dev/null +++ b/GUI/ActiveThreads.aspx @@ -0,0 +1,115 @@ +<%@ Page language="c#" CodeFile="ActiveThreads.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.ActiveThreads" %> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageList" Src="PageList.ascx"%> +<%@ Import namespace="System.Web" %> +<%@ Import Namespace="System.Globalization" %> +<%@ Import Namespace="SD.HnD.GUI" %> +<%@ Register TagPrefix="HnD" TagName="PageLegend" Src="PageLegend.ascx"%> + + + + HnD::Active threads + + + +

+ + + + + +
+
+ You are here: Home > Active threads +

+
+ + + + + + + + + + +
+ Active threads +
+ The list of all active threads of the past <%=CacheManager.GetSystemData().HoursThresholdForActiveThreads%> hours. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Thread subjectRepliesViewsLast post
+ + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +    
+
Posted in forum: <%# Eval("ForumName")%>.
+ Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
+
<%# (int)Eval("AmountMessages") - 1%><%# Eval("NumberOfViews")%> +
By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
+ On:
+
+ + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +    
+
Posted in forum: <%# Eval("ForumName")%>.
+ Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
+
<%# (int)Eval("AmountMessages") - 1%><%# Eval("NumberOfViews")%> +
By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
+ On:
+
+ +
+ + +
+
+ + + + diff --git a/GUI/ActiveThreads.aspx.cs b/GUI/ActiveThreads.aspx.cs new file mode 100644 index 0000000..a3a4d84 --- /dev/null +++ b/GUI/ActiveThreads.aspx.cs @@ -0,0 +1,141 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; + +namespace SD.HnD.GUI +{ + /// + /// Form which views all active threads. An active thread is a thread which isn't marked done. + /// + public partial class ActiveThreads : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // fill the page's content + List accessableForums = SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum); + DataView activeThreads = ThreadGuiHelper.GetActiveThreadsAsDataView(accessableForums, CacheManager.GetSystemData().HoursThresholdForActiveThreads, + SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), SessionAdapter.GetUserID()); + rpThreads.DataSource = activeThreads; + rpThreads.DataBind(); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + this.rpThreads.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.rpThreads_ItemDataBound); + } + #endregion + + + /// + /// Event handler which will be called every time a row in the Repeater rpThreads is bound to a row in the view. + /// + /// + /// + private void rpThreads_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + // Thread has always a last posting date: a thread has at least 1 posting. + DateTime threadLastPostingDate = (DateTime)(((DataRowView)e.Item.DataItem)["ThreadLastPostingDate"]); + DateTime lastVisitDate = SessionAdapter.GetLastVisitDate(); + bool isSticky = (bool)(((DataRowView)e.Item.DataItem)["IsSticky"]); + bool isClosed = (bool)(((DataRowView)e.Item.DataItem)["IsClosed"]); + + // date is not 0, check if the date is > than the date in the session variable. If so, the posting is newer and we + // should visualize the New Messages image, otherwise the No new Messages image. Also take into account + // the type of the thread: sticky, closed or normal. + System.Web.UI.WebControls.Image imgIconPosts; + + if(threadLastPostingDate > lastVisitDate) + { + // there are new messages since last visit + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPosts"); + } + } + } + else + { + // no new messages + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPosts"); + } + } + } + imgIconPosts.Visible = true; + break; + } + } + } +} diff --git a/GUI/Admin/AddForum.aspx b/GUI/Admin/AddForum.aspx new file mode 100644 index 0000000..7d126f7 --- /dev/null +++ b/GUI/Admin/AddForum.aspx @@ -0,0 +1,191 @@ +<%@ Page language="c#" CodeFile="AddForum.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.AddForum" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Add a new forum"%> + + + + + + +
+

Add a new forum

+ Adds a new forum to the system immediately. The forum will be added to the section you specify however no forum rights are + assigned to any role for this forum, therefore it will not show up in the forum + list of the section specified until you assign at least access rights for this forum to some role in the system. +

+ The default support queue is the queue to which threads in the forum are added to if the thread is new, or gets a new message. + Assign only a support queue to a forum if messages in the forum require attention from a special group of users who have queue contents management + access rights. +
+

+ + + + + + + + +
+ Existing forums +
+ The list of existing forums in the forum system, including the sections they're in. +
+ + + + + + + + + + + + + + + + + + + + + + + + +
Forum nameLocated in sectionSort-order no
+ <%#Eval("ForumName") %>
+ <%#Eval("ForumDescription")%> +
+ <%#Eval("SectionName") %>
+
+ <%#Eval("ForumOrderNo") %>
+
+ <%#Eval("ForumName") %>
+ <%#Eval("ForumDescription")%> +
+ <%#Eval("SectionName") %>
+
+ <%#Eval("ForumOrderNo") %>
+
+
 
+ + + + + + + + + + +
+ Add a new forum +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Forum name 
Description  + +
Place in section  + +
Has RSS Feed  + + Warning: Be aware that everyone can see messages posted in this forum via an RSS feed. If you don't want that, don't + enable an RSS feed on this forum +
+ Default Support queue  + + + +
+ Default thread interval  + + + + + + + +
Sort-order no.  + +
Max. # attachments per message  + +
Max. attachment size  + KB +
New thread welcome text 
(optional) 
+ +
+ You can use all normal message UBB tags in this text. All line breaks will be line breaks when the text is shown and + all URLs are automatically converted, please prefix any URL with http:// or https://. The New thread welcome text is shown + when a new thread is started, above the message box. +
  +
+
+
  +
+ +
+
+ +
\ No newline at end of file diff --git a/GUI/Admin/AddForum.aspx.cs b/GUI/Admin/AddForum.aspx.cs new file mode 100644 index 0000000..05bc5f2 --- /dev/null +++ b/GUI/Admin/AddForum.aspx.cs @@ -0,0 +1,132 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.DAL.TypedListClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the AddForum form. + /// + public partial class AddForum : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if(!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if (!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // Read all the current existing forums and their section names. + ForumsWithSectionNameTypedList forumsWithSectionNames = ForumGuiHelper.GetAllForumsWithSectionNames(); + rpForums.DataSource = forumsWithSectionNames; + rpForums.DataBind(); + + SectionCollection sections = SectionGuiHelper.GetAllSections(); + cbxSections.DataSource = sections; + cbxSections.DataBind(); + + SupportQueueCollection supportQueues = CacheManager.GetAllSupportQueues(); + cbxSupportQueues.DataSource = supportQueues; + cbxSupportQueues.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + int? supportQueueID = null; + int selectedSupportQueueID = Convert.ToInt32(cbxSupportQueues.SelectedItem.Value); + if(selectedSupportQueueID > 0) + { + supportQueueID = selectedSupportQueueID; + } + + string newThreadWelcomeText = null; + string newThreadWelcomeTextAsHTML = null; + if(tbxNewThreadWelcomeText.Text.Trim().Length > 0) + { + // has specified welcome text, convert to HTML + newThreadWelcomeText = tbxNewThreadWelcomeText.Text.Trim(); + string parserLog, textAsXML; + bool errorsOccured; + newThreadWelcomeTextAsHTML = TextParser.TransformUBBMessageStringToHTML(newThreadWelcomeText, ApplicationAdapter.GetParserData(), + out parserLog, out errorsOccured, out textAsXML); + } + + // store the data as a new forum. + int forumID = ForumManager.CreateNewForum(HnDGeneralUtils.TryConvertToInt(cbxSections.SelectedItem.Value), tbxForumName.Value, + tbxForumDescription.Text, chkHasRSSFeed.Checked, supportQueueID, HnDGeneralUtils.TryConvertToInt(cbxThreadListInterval.SelectedValue), + HnDGeneralUtils.TryConvertToShort(tbxOrderNo.Text), HnDGeneralUtils.TryConvertToInt(tbxMaxAttachmentSize.Text), + HnDGeneralUtils.TryConvertToShort(tbxMaxNoOfAttachmentsPerMessage.Text), newThreadWelcomeText, newThreadWelcomeTextAsHTML); + + // done for now, redirect to self + Response.Redirect("AddForum.aspx", true); + } + } + } +} diff --git a/GUI/Admin/AddRole.aspx b/GUI/Admin/AddRole.aspx new file mode 100644 index 0000000..b73c859 --- /dev/null +++ b/GUI/Admin/AddRole.aspx @@ -0,0 +1,87 @@ +<%@ Page language="c#" CodeFile="AddRole.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.AddRole" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Add a new role"%> + + + + + + + + + + +
+ Existing roles +
+ The list of existing roles in the forum system. +
+ + + + + + + + + + + + + + +
+ <%#Eval("RoleDescription")%>
+ This role is used for anonymous users. + This role is assigned to new users. +
+ <%#Eval("RoleDescription")%>
+ This role is used for anonymous users. + This role is assigned to new users. +
+
 
+
+ + + + + + + + + + +
+ Add a new role +
+ + Adds a new role to the system immediately. A new role doesn't have any rights assigned to it nor are there any users placed in this role. + +
+ + + + + + + + + + + + + + + + + +

Role description  + +
  +
+
+
  +
+ There was an error saving the role, this can be caused by a role that has the same description. +
+
+
\ No newline at end of file diff --git a/GUI/Admin/AddRole.aspx.cs b/GUI/Admin/AddRole.aspx.cs new file mode 100644 index 0000000..e94910f --- /dev/null +++ b/GUI/Admin/AddRole.aspx.cs @@ -0,0 +1,109 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the AddRole form. + /// + public partial class AddRole : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // bind the Roles repeater to a dataview with all sections. + DataView rolesWithStatistics = SecurityGuiHelper.GetAllRolesWithStatisticsAsDataView(); + + rpRoles.DataSource = rolesWithStatistics; + rpRoles.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + // Save the new role. + int roleID = SecurityManager.CreateNewRole(tbxRoleDescription.Text); + + if(roleID > 0) + { + // succeeded + Response.Redirect("AddRole.aspx", true); + } + else + { + // same description error + lblDuplicateRoleDescription.Visible=true; + } + } + } + } +} diff --git a/GUI/Admin/AddSection.aspx b/GUI/Admin/AddSection.aspx new file mode 100644 index 0000000..a364e4d --- /dev/null +++ b/GUI/Admin/AddSection.aspx @@ -0,0 +1,109 @@ +<%@ Page language="c#" CodeFile="AddSection.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.AddSection" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Add a new section"%> + + + + + + + + + + +
+ Existing sections +
+ The list of existing sections in the forum system. +
+ + + + + + + + + + + + + + + + + + + + +
Section NameSort-order no.
+ <%#Eval("SectionName") %>
+ <%#Eval("SectionDescription")%> +
+ <%# Eval("OrderNo") %> +
+ <%#Eval("SectionName") %>
+ <%#Eval("SectionDescription")%> +
+ <%# Eval("OrderNo") %> +
+
 
+
+ + + + + + + + + + + +
+ Add a new section +
+ Adds a new section to the system immediately. A new section doesn't have any forums. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

 Section name 
 Description  + +
 Sort-order no.  + +
  +
+
+
  +
+ +
+
+
\ No newline at end of file diff --git a/GUI/Admin/AddSection.aspx.cs b/GUI/Admin/AddSection.aspx.cs new file mode 100644 index 0000000..9de4e5a --- /dev/null +++ b/GUI/Admin/AddSection.aspx.cs @@ -0,0 +1,101 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the AddSection form. + /// + public partial class AddSection : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // bind the sections repeater to a collection with all sections. + SectionCollection sections = SectionGuiHelper.GetAllSections(); + rpSections.DataSource = sections; + rpSections.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + // Save the form contents. + int sectionID = SectionManager.AddNewSection(tbxSectionName.Value, tbxSectionDescription.Text, HnDGeneralUtils.TryConvertToShort(tbxOrderNo.Text)); + + // done, redirect to self + Response.Redirect("AddSection.aspx", true); + } + } + } +} diff --git a/GUI/Admin/AddUsersToRole.aspx b/GUI/Admin/AddUsersToRole.aspx new file mode 100644 index 0000000..f24f95b --- /dev/null +++ b/GUI/Admin/AddUsersToRole.aspx @@ -0,0 +1,54 @@ +<%@ Page language="c#" CodeFile="AddUsersToRole.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.AddUsersToRole" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Add users to role"%> + + + + + + +
+

Add users to role.

+ Below you'll find all existing users in the system who are not currently part of the role <%=base.RoleDescription%>. + All users are shown, also the users who are banned. This way you can create additional ban functionality based on role security. +

+ You can select multiple users by holding down control and left clicking nicknames. When you're done, click Add user(s) to add the + selected users to the role or click Cancel to go back to the role list. +
+
+ + + + + + + + + + +
+ Select users to add to the role <%=base.RoleDescription%> +
+ Adds all selected users to the given role. Hold down the control (ctrl) key while left-clicking the + names to multi-select users. +
+ + + + + + + + + + + + +

Users not in role  + +
  +
+     + +
+
+
\ No newline at end of file diff --git a/GUI/Admin/AddUsersToRole.aspx.cs b/GUI/Admin/AddUsersToRole.aspx.cs new file mode 100644 index 0000000..833efac --- /dev/null +++ b/GUI/Admin/AddUsersToRole.aspx.cs @@ -0,0 +1,145 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using System.Collections.Generic; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind for the form which allows an administrator to add users to a role. + /// + public partial class AddUsersToRole : System.Web.UI.Page + { + #region Class Member declarations + private int _roleID; + private string _roleDescription; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _roleID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["RoleID"]); + + if(!Page.IsPostBack) + { + // Get Role + RoleEntity role = SecurityGuiHelper.GetRole(_roleID); + _roleDescription = role.RoleDescription; + + // bind the users listbox to an entitycollection with all users. + UserCollection users = UserGuiHelper.GetAllUsersNotInRole(_roleID); + + lbxUsers.DataSource = users; + lbxUsers.DataTextField = "NickName"; + lbxUsers.DataValueField = "UserID"; + lbxUsers.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnAddUsers.ServerClick += new System.EventHandler(this.btnAddUsers_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + + private void btnAddUsers_ServerClick(object sender, System.EventArgs e) + { + // add all selected users to the role + List userIDsToAdd = new List(); + + for(int i = 0; i < lbxUsers.Items.Count; i++) + { + ListItem userItem = lbxUsers.Items[i]; + if(userItem.Selected) + { + userIDsToAdd.Add(Convert.ToInt32(userItem.Value)); + } + } + + // add them + bool result = SecurityManager.AddUsersToRole(userIDsToAdd, _roleID); + // enough for now + Response.Redirect("ManageUsersInRole.aspx", true); + } + + + private void btnCancel_ServerClick(object sender, System.EventArgs e) + { + // do nothing + Response.Redirect("ManageUsersInRole.aspx", true); + } + + + #region Class Property Declarations + /// + /// Gets the role description of the active role. + /// + /// The role description. + protected string RoleDescription + { + get { return _roleDescription; } + } + #endregion + } +} diff --git a/GUI/Admin/AdminMaster.master b/GUI/Admin/AdminMaster.master new file mode 100644 index 0000000..911abce --- /dev/null +++ b/GUI/Admin/AdminMaster.master @@ -0,0 +1,21 @@ +<%@ Master Language="C#" AutoEventWireup="true" CodeFile="AdminMaster.master.cs" Inherits="SD.HnD.GUI.Admin.AdminMaster" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="../Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> + + + HnD::Administrate + + + +
+ +
+ + +
+ + +
+ + + diff --git a/GUI/Admin/AdminMaster.master.cs b/GUI/Admin/AdminMaster.master.cs new file mode 100644 index 0000000..88ce51a --- /dev/null +++ b/GUI/Admin/AdminMaster.master.cs @@ -0,0 +1,46 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI.Admin +{ + public partial class AdminMaster : System.Web.UI.MasterPage + { + protected void Page_Load(object sender, EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if(!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx", true); + } + } + } +} \ No newline at end of file diff --git a/GUI/Admin/BanUnBanUser.aspx b/GUI/Admin/BanUnBanUser.aspx new file mode 100644 index 0000000..0914aba --- /dev/null +++ b/GUI/Admin/BanUnBanUser.aspx @@ -0,0 +1,46 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="BanUnBanUser.aspx.cs" Inherits="SD.HnD.GUI.Admin.BanUnbanUser" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Ban/unban a user"%> +<%@ Register TagPrefix="HnD" TagName="FindUser" Src="FindUser.ascx"%> + + + + + + +
+

Ban/unban a user.

+ Below you can ban or unban a user. First select the user to ban/unban using the Find User portion of the form, then you've to confirm you want to + ban / unban the user selected. + You can't ban yourself nor the Anonymous Coward user (UserID 0). The ban is set on the user account and the user will be logged out by force + the next time the user requests a forum page. +
+

+ + +
+ + + + + +
+ Current ban status for user (): + +

+ Are you sure you want to toggle the ban flag for this user? +

+      + +
+
+ + + + + + +
+ Toggle of banflag value was successful. +
+
+
\ No newline at end of file diff --git a/GUI/Admin/BanUnBanUser.aspx.cs b/GUI/Admin/BanUnBanUser.aspx.cs new file mode 100644 index 0000000..3f2931a --- /dev/null +++ b/GUI/Admin/BanUnBanUser.aspx.cs @@ -0,0 +1,123 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.GUI; +using SD.HnD.BL; +using System.Collections.Generic; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// The code behind file for the form to ban / unban a single user account + /// + public partial class BanUnbanUser : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if(!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx", true); + } + + // Check if the user has the right systemright + bool userHasAccess = SessionAdapter.HasSystemActionRight(ActionRights.UserManagement); + if(!userHasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx", true); + } + } + + + /// + /// Handler for the selectclicked event of the finduser control. + /// + /// + /// + protected void SelectClickedHandler(object sender, System.EventArgs e) + { + phToggleResult.Visible = false; + + List selectedUserIDs = userFinder.SelectedUserIDs; + if(selectedUserIDs.Count < 0) + { + // nothing selected, return + return; + } + + // just use the first selected user + int selectedUserID = selectedUserIDs[0]; + if((selectedUserID == 0) || (selectedUserID == SessionAdapter.GetUserID())) + { + // can't ban anonymous coward or him/herself + return; + } + + UserEntity user = UserGuiHelper.GetUser(selectedUserID); + lblNickname.Text = user.NickName; + lblUserID.Text = user.UserID.ToString(); + if(user.IsBanned) + { + lblBanStatus.Text = "banned"; + } + else + { + lblBanStatus.Text = "not banned"; + } + + phUserInfo.Visible = true; + } + + + protected void btnYes_Click(object sender, EventArgs e) + { + bool newBanFlagValue = false; + bool result = UserManager.ToggleBanFlagValue(HnDGeneralUtils.TryConvertToInt(lblUserID.Text), out newBanFlagValue); + phToggleResult.Visible = result; + phUserInfo.Visible = !result; + if(newBanFlagValue) + { + // add the user to be logged out by force. + ApplicationAdapter.AddUserToListToBeLoggedOutByForce(lblNickname.Text); + } + } + + + protected void btnNo_Click(object sender, EventArgs e) + { + phToggleResult.Visible = false; + phUserInfo.Visible = false; + } + } +} \ No newline at end of file diff --git a/GUI/Admin/Default.aspx b/GUI/Admin/Default.aspx new file mode 100644 index 0000000..70bfb9d --- /dev/null +++ b/GUI/Admin/Default.aspx @@ -0,0 +1,184 @@ +<%@ Page language="c#" CodeFile="Default.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin._Default" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate your forumsystem" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="../Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> + + + + + + +
+

Administrate your forumsystem

+ Below you'll find the menu for the different actions you can perform on this forum system. + When a menu section is not available to you because you don't have the proper access rights, the + menu section header is visible, but the options are not. + All actions performed through this administration menu are + done on the live database and all your actions are active as soon as you finish your action. + Be aware of that fact when you perform actions on your forum system. +
+
+ + + + + + + + +
+ System management +
+ System management tasks +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
System parameters
+ Modify system parameters
+ Allows you to modify system parameters such as the default user role assigned to new users. +
+ Re-parse messages
+ Re-parses messages and stores their updated XML into the db. +
Support queues
+ Manage support queues
+ Allows you to add, edit and remove a support queue and its details. +
Sections
+ Add new section
+ Allows you to add a new section to the forum system wherein you can add new forums. +
+ Modify / Delete section
+ Allows you to modify or delete an existing section in the forum system. + You can change name and description of the section and also which forums are in the section. + When you delete a section, the forums in that section should first be removed or moved to + other sections. You can only delete empty sections. +
Forums
+ Add new Forum
+ Allows you to add a new forum to the forum system. +
+ Modify / Delete Forum
+ + Allows you to modify / delete an existing forum in the forum system. + You can change name and description of the forum and also in + which section a particular forum is located. + When you delete a forum, all threads and messages in that forum are removed as well. +
Users
+ Ban / Unban a user
+ Allows you to ban or unban a user from the forum system, based on a user account ban. +
+ Modify user information
+ Allows you to modify a user's profile and reset the user's password etc. +
+ Delete user
+ Allows you to delete a user. Use this as a last resort, since all the messages + the user has posted will be assigned to the Anonymous Coward user (UserID 0). +
+ View audit information for a user
+ Allows you to view the latest logged audit information for a particular user. +
+ Send email to user(s)
+ Allows you to email one or more users directly from the forum system. +
+ Manage IP bans
+ Allows you add / edit or remove an IP ban. An IP ban is a ban which allows you to ban a range + of IP addresses or just one address. +
Security
+ Add Role
+ Allows you add a new role to the forum system. +
+ Modify / Delete Role
+ Allows you to modify a role or delete a role alltogether. + You can change the description and which system rights the role has. +
+ Manage Users in Role
+ Allows you to modify which users are in the role. +
+ Manage Role rights per Forum
+ Allows you to assign per forum the rights for a role. +
+ Manage Audit Actions per Role
+ Allows you to modify which audit actions are set for a specifc role. +
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/Default.aspx.cs b/GUI/Admin/Default.aspx.cs new file mode 100644 index 0000000..b1abfb8 --- /dev/null +++ b/GUI/Admin/Default.aspx.cs @@ -0,0 +1,87 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the Default form of the Admin section. + /// + public partial class _Default : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + if(SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // can perform system management tasks. Visualize menu + phSections.Visible=true; + phForums.Visible=true; + phSystem.Visible=true; + } + + if(SessionAdapter.HasSystemActionRight(ActionRights.UserManagement)) + { + // can perform user management tasks, visualize menu + phUsers.Visible=true; + } + + if(SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // can perform security management tasks, visualize menu. + phSecurity.Visible=true; + } + + // switch off the link back to the admin menu as this page holds the admin menu. + SD.HnD.GUI.Admin.Header pageHeader = (SD.HnD.GUI.Admin.Header)Master.FindControl("_pageHeader"); + pageHeader.MenuReturnLinkVisible = false; + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + } +} diff --git a/GUI/Admin/DeleteForum.aspx b/GUI/Admin/DeleteForum.aspx new file mode 100644 index 0000000..254d8df --- /dev/null +++ b/GUI/Admin/DeleteForum.aspx @@ -0,0 +1,61 @@ +<%@ Page language="c#" CodeFile="DeleteForum.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.DeleteForum" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Delete a forum"%> + + + + + + +
+

Delete a forum

+ Below you'll see the forum you selected for deletion. When you proceed with deleting this forum, all messages posted in this forum + are deleted with the threads they're in plus all message history logs are also removed. Only remove a forum if you really want to get rid of + all the discussions posted in the forum. +

+ You can proceed with the deletion of the forum by clicking on the Delete button. If + you don't want to delete this forum, click on the Keep button. The delete action is irreversable. +
+
+ + + + + + + + + + + + + +
+ Forum marked for deletion +
+ + + + + +
  +
+
+ +
+
+
+ + + + + + + +

+
+
+       +
+
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/DeleteForum.aspx.cs b/GUI/Admin/DeleteForum.aspx.cs new file mode 100644 index 0000000..2701155 --- /dev/null +++ b/GUI/Admin/DeleteForum.aspx.cs @@ -0,0 +1,135 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the DeleteForum form. + /// + public partial class DeleteForum : System.Web.UI.Page + { + private int _forumID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright; + if (!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _forumID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ForumID"]); + + if(!Page.IsPostBack) + { + + // Get the forum + try + { + ForumEntity forum = ForumGuiHelper.GetForum(_forumID); + + // Show results in the labels + if(forum!=null) + { + // the forum exists + lblForumName.Text = forum.ForumName; + lblForumDescription.Text = forum.ForumDescription; + } + else + { + // the forum doesn't exist anymore + Response.Redirect("ModifyDeleteForum.aspx",true); + } + } + catch(Exception ex) + { + // Bubble + throw ex; + } + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnDelete.ServerClick += new System.EventHandler(this.btnDelete_ServerClick); + this.btnKeep.ServerClick += new System.EventHandler(this.btnKeep_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + + private void btnDelete_ServerClick(object sender, System.EventArgs e) + { + // delete the forum. + bool result = ForumManager.DeleteForum(_forumID); + + // invalidate cache + CacheManager.InvalidateCachedItem(CacheManager.ProduceCacheKey(CacheKeys.SingleForum, _forumID)); + + // Done + Response.Redirect("ModifyDeleteForum.aspx",true); + } + + + private void btnKeep_ServerClick(object sender, System.EventArgs e) + { + // do nothing + Response.Redirect("ModifyDeleteForum.aspx",true); + } + } +} diff --git a/GUI/Admin/DeleteRole.aspx b/GUI/Admin/DeleteRole.aspx new file mode 100644 index 0000000..e6fc46a --- /dev/null +++ b/GUI/Admin/DeleteRole.aspx @@ -0,0 +1,64 @@ +<%@ Page language="c#" CodeFile="DeleteRole.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.DeleteRole" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Delete a role"%> + + + + + + +
+

Delete a role

+ Below you'll see the role you selected for deletion. Together with this role, all rights assigned to this role are + removed. You can't delete the role for anonymous users (users who visit the forum system but are not logged in) + or the role which is default assigned to new users. + You can change which roles are used for anonymous users or for new users in + Modify system parameters, if you have the proper access rights for that. Delete roles + only if you do not need them and they are empty; most of the time you do not need to delete roles, you can simply remove the users + from the role or remove the rights from the role. +

+ If you want to proceed with the deletion, click the Delete button. If + you don't want to delete this role, click on the Keep button. The delete action is irreversable. +
+
+ + + + + + + + + + + + + +
+ Role marked for deletion +
+ + + + + +
  +
+ +
+
+
+ + + + + + + +

+
+
+       +
+
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/DeleteRole.aspx.cs b/GUI/Admin/DeleteRole.aspx.cs new file mode 100644 index 0000000..1b60e36 --- /dev/null +++ b/GUI/Admin/DeleteRole.aspx.cs @@ -0,0 +1,113 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the DeleteRole form. + /// + public partial class DeleteRole : System.Web.UI.Page + { + private int _roleID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _roleID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["RoleID"]); + + if(!Page.IsPostBack) + { + // get the role and show the description + RoleEntity role = SecurityGuiHelper.GetRole(_roleID); + + if(!role.IsNew) + { + lblRoleDescription.Text = role.RoleDescription; + } + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnDelete.ServerClick += new System.EventHandler(this.btnDelete_ServerClick); + this.btnKeep.ServerClick += new System.EventHandler(this.btnKeep_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnDelete_ServerClick(object sender, System.EventArgs e) + { + // delete the role + bool result = SecurityManager.DeleteRole(_roleID); + + // done for now + Response.Redirect("ModifyDeleteRole.aspx", true); + } + + private void btnKeep_ServerClick(object sender, System.EventArgs e) + { + // do nothing + Response.Redirect("ModifyDeleteRole.aspx", true); + } + } +} diff --git a/GUI/Admin/DeleteSection.aspx b/GUI/Admin/DeleteSection.aspx new file mode 100644 index 0000000..81553e8 --- /dev/null +++ b/GUI/Admin/DeleteSection.aspx @@ -0,0 +1,66 @@ +<%@ Page language="c#" CodeFile="DeleteSection.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.DeleteSection" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Delete a section"%> + + + + + + +
+

Delete a section

+ Below you'll see the section you selected for deletion. This section can't have + any forums. If there are still forums in the section, the form below will + notify you on that and you can't delete the section. If the section is empty, + you can safely delete the section by clicking on the Delete button. If + you don't want to delete this section, click on the Keep button. The delete + action is irreversable. +
+
+ + + + + + + + + + + + + +
+ Section marked for deletion +
+ + + + + +
  +
+
+ + +
+
+
+ + + + + + + +

+ + Note: This section isn't empty, and therefor you're not able to delete this section. Remove / move the existing + forum(s) in this section first before deleting this section. + +
+
+       +
+
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/DeleteSection.aspx.cs b/GUI/Admin/DeleteSection.aspx.cs new file mode 100644 index 0000000..a563b79 --- /dev/null +++ b/GUI/Admin/DeleteSection.aspx.cs @@ -0,0 +1,138 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the DeleteSection form. + /// + public partial class DeleteSection : System.Web.UI.Page + { + protected int _sectionID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _sectionID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["SectionID"]); + + if(!Page.IsPostBack) + { + // Get the section directly from the DB, instead from the in-memory cache + SectionEntity section = SectionGuiHelper.GetSection(_sectionID); + + // Show results in the labels + if(section!=null) + { + // Section found + // Get the forums in the section + ForumCollection forums = ForumGuiHelper.GetAllForumsInSection(_sectionID); + if(forums.Count > 0) + { + // section has forums. User is not able to delete the section. Show error message plus + // disable delete button + lblRuleError.Visible=true; + btnDelete.Disabled=true; + } + lblSectionName.Text = section.SectionName; + lblSectionDescription.Text = section.SectionDescription; + } + else + { + // the section doesn't exist anymore + Response.Redirect("ModifyDeleteSection.aspx",true); + } + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnDelete.ServerClick += new System.EventHandler(this.btnDelete_ServerClick); + this.btnKeep.ServerClick += new System.EventHandler(this.btnKeep_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnDelete_ServerClick(object sender, System.EventArgs e) + { + // user wants to delete the section + bool result = SectionManager.DeleteSection(_sectionID); + + if (result) + { + // succeeded. + // invalidate cache + CacheManager.InvalidateCachedItem(CacheKeys.AllSections); + + // redirect to modifydelete form + Response.Redirect("ModifyDeleteSection.aspx",true); + } + } + + private void btnKeep_ServerClick(object sender, System.EventArgs e) + { + // nothing should happen, redirect to section listing + Response.Redirect("ModifyDeleteSection.aspx",true); + } + } +} diff --git a/GUI/Admin/DeleteUser.aspx b/GUI/Admin/DeleteUser.aspx new file mode 100644 index 0000000..45ccf86 --- /dev/null +++ b/GUI/Admin/DeleteUser.aspx @@ -0,0 +1,41 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DeleteUser.aspx.cs" Inherits="SD.HnD.GUI.Admin.DeleteUser" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Delete a user"%> +<%@ Register TagPrefix="HnD" TagName="FindUser" Src="FindUser.ascx"%> + + + + + + +
+

Delete a user.

+ Below you can delete a user. First select the user to delete using the Find User portion of the form, then you've to confirm you want to delete the user + selected. You can't delete yourself nor the Anonymous Coward user (UserID 0). +
+

+ + +
+ + + + + +
+ Are you sure you want to delete user () ? +

+      + +
+
+ + + + + + +
+ User deleted succesfully. +
+
+
\ No newline at end of file diff --git a/GUI/Admin/DeleteUser.aspx.cs b/GUI/Admin/DeleteUser.aspx.cs new file mode 100644 index 0000000..8982bc2 --- /dev/null +++ b/GUI/Admin/DeleteUser.aspx.cs @@ -0,0 +1,113 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.GUI; +using SD.HnD.BL; +using System.Collections.Generic; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the form to delete a user account. + /// + public partial class DeleteUser : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if(!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx", true); + } + + // Check if the user has the right systemright + bool userHasAccess = SessionAdapter.HasSystemActionRight(ActionRights.UserManagement); + if(!userHasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx", true); + } + } + + + /// + /// Handler for the selectclicked event of the finduser control. + /// + /// + /// + protected void SelectClickedHandler(object sender, System.EventArgs e) + { + phDeleteResult.Visible = false; + + List selectedUserIDs = userFinder.SelectedUserIDs; + if(selectedUserIDs.Count < 0) + { + // nothing selected, return + return; + } + + // just use the first selected user + int selectedUserID = selectedUserIDs[0]; + if((selectedUserID == 0) || (selectedUserID == SessionAdapter.GetUserID())) + { + // can't delete anonymous coward or him/herself + return; + } + + UserEntity user = UserGuiHelper.GetUser(selectedUserID); + lblNickname.Text = user.NickName; + lblUserID.Text = user.UserID.ToString(); + phUserInfo.Visible = true; + } + + + protected void btnYes_Click(object sender, EventArgs e) + { + bool result = UserManager.DeleteUser(HnDGeneralUtils.TryConvertToInt(lblUserID.Text)); + phDeleteResult.Visible = result; + phUserInfo.Visible = !result; + if(result) + { + ApplicationAdapter.AddUserToListToBeLoggedOutByForce(lblNickname.Text); + } + } + + + protected void btnNo_Click(object sender, EventArgs e) + { + phDeleteResult.Visible = false; + phUserInfo.Visible = false; + } + } +} \ No newline at end of file diff --git a/GUI/Admin/FindUser.ascx b/GUI/Admin/FindUser.ascx new file mode 100644 index 0000000..67b78e1 --- /dev/null +++ b/GUI/Admin/FindUser.ascx @@ -0,0 +1,58 @@ +<%@ Control Language="c#" AutoEventWireup="false" CodeFile="FindUser.ascx.cs" Inherits="SD.HnD.GUI.Admin.FindUser" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> + + + + + + + + + + + + + + + +
+ Find <%=_description%> +
+ Find <%=_description%> by Role, Nickname or email address. +
+ + + + + + + + + + + + + + + + + + + + +
 Filter on role
 Filter on nickname
 Filter on emailaddress
  +
+ +

+
+
+ Users matching the filter + + + + +
+ +
+ +
+
\ No newline at end of file diff --git a/GUI/Admin/FindUser.ascx.cs b/GUI/Admin/FindUser.ascx.cs new file mode 100644 index 0000000..aaae82b --- /dev/null +++ b/GUI/Admin/FindUser.ascx.cs @@ -0,0 +1,227 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +namespace SD.HnD.GUI.Admin +{ + using System; + using System.Data; + using System.Drawing; + using System.Web; + using System.Web.UI.WebControls; + using System.Web.UI.HtmlControls; + using System.Collections; + + using SD.LLBLGen.Pro.ORMSupportClasses; + using SD.HnD.DAL.CollectionClasses; + using SD.HnD.DAL.EntityClasses; + using SD.HnD.BL; + using System.Collections.Generic; + + /// + /// Summary description for FindUser. + /// + public partial class FindUser : System.Web.UI.UserControl + { + #region Events + public event EventHandler SelectClicked; + #endregion + + #region Class Member Declarations + protected string _description; + + private bool _multiSelect; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + _description = "user"; + if(_multiSelect) + { + _description = "users"; + } + + if(!Page.IsPostBack) + { + RoleCollection roles = SecurityGuiHelper.GetAllRoles(); + cbxRoles.DataSource = roles; + cbxRoles.DataTextField = "RoleDescription"; + cbxRoles.DataValueField = "RoleID"; + cbxRoles.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + /// + /// General event bubbler. All events of controls contained by this container are streaming through this bubbler. + /// + /// + /// + /// + protected override bool OnBubbleEvent(object source, EventArgs e) + { + bool bHandled = false; + + CommandEventArgs ceArgs = e as CommandEventArgs; + if(ceArgs != null) + { + switch(ceArgs.CommandName) + { + case "btnFindUsers": + OnFind(ceArgs); + bHandled = true; + break; + case "btnSelect": + OnSelect(ceArgs); + break; + } + } + return bHandled; + } + + + /// + /// Finds the user specified in the filter. + /// + /// The instance containing the event data. + protected virtual void OnFind(EventArgs e) + { + if(!(chkFilterOnRole.Checked || chkFilterOnNickName.Checked || chkFilterOnEmailAddress.Checked)) + { + // nothing selected + return; + } + + UserCollection matchingUsers = UserGuiHelper.FindUsers(chkFilterOnRole.Checked, Convert.ToInt32(cbxRoles.SelectedValue), + chkFilterOnNickName.Checked, tbxNickName.Text.Trim(), + chkFilterOnEmailAddress.Checked, tbxEmailAddress.Text.Trim()); + + lbxMatchingUsers.DataSource = matchingUsers; + lbxMatchingUsers.DataTextField = "NickName"; + lbxMatchingUsers.DataValueField = "UserID"; + lbxMatchingUsers.DataBind(); + phSearchResults.Visible = true; + btnSelect.Enabled = (matchingUsers.Count>0); + } + + + /// + /// Raises the SelectClicked event. + /// + /// The instance containing the event data. + protected virtual void OnSelect(EventArgs e) + { + if(lbxMatchingUsers.SelectedIndex<0) + { + return; + } + + if(SelectClicked!=null) + { + SelectClicked(this, new EventArgs()); + } + } + + + #region Class Property Declarations + /// + /// Sets the button description. + /// + /// The button description. + public string ButtonDescription + { + set + { + btnSelect.Text = value; + } + } + + /// + /// Gets / sets multiSelect + /// + public bool MultiSelect + { + get + { + return _multiSelect; + } + set + { + _multiSelect = value; + if(value) + { + lbxMatchingUsers.SelectionMode = ListSelectionMode.Multiple; + } + else + { + lbxMatchingUsers.SelectionMode = ListSelectionMode.Single; + } + } + } + + + /// + /// Gets the selected userIDs. + /// + public List SelectedUserIDs + { + get + { + List toReturn = new List(); + if(_multiSelect) + { + foreach(ListItem item in lbxMatchingUsers.Items) + { + if(item.Selected) + { + toReturn.Add(Convert.ToInt32(item.Value)); + } + } + } + else + { + toReturn.Add(Convert.ToInt32(lbxMatchingUsers.SelectedValue)); + } + + return toReturn; + } + } + + #endregion + } +} diff --git a/GUI/Admin/Header.ascx b/GUI/Admin/Header.ascx new file mode 100644 index 0000000..28dc39a --- /dev/null +++ b/GUI/Admin/Header.ascx @@ -0,0 +1,22 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Header.ascx.cs" Inherits="SD.HnD.GUI.Admin.Header" ClassName="Header" %> + + + + +
+ + + + + + +
+ + +
+ + Administrate home + +
 
+
+
diff --git a/GUI/Admin/Header.ascx.cs b/GUI/Admin/Header.ascx.cs new file mode 100644 index 0000000..e428bd5 --- /dev/null +++ b/GUI/Admin/Header.ascx.cs @@ -0,0 +1,50 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the header of the admin pages. + /// + public partial class Header : System.Web.UI.UserControl + { + protected void Page_Load(object sender, EventArgs e) + { + } + + /// + /// Set to false to hide the return menu link in the header. + /// + public bool MenuReturnLinkVisible + { + set { phMenuLink.Visible = value; } + } + } +} \ No newline at end of file diff --git a/GUI/Admin/ManageAuditActionsPerRole.aspx b/GUI/Admin/ManageAuditActionsPerRole.aspx new file mode 100644 index 0000000..af3e60f --- /dev/null +++ b/GUI/Admin/ManageAuditActionsPerRole.aspx @@ -0,0 +1,68 @@ +<%@ Page language="c#" CodeFile="ManageAuditActionsPerRole.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ManageAuditActionsPerRole" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Manage Audit Actions per role"%> + + + + + + +
+

Manage Audit Actions per Role

+ Below you can configure the audit action definitions per role. You first select the role you want to define the audit actions for, then + you check / uncheck every audit action to set the audit actions for the role selected. When you are done, click Save to + save the definition or click Cancel to go back to the main menu. Once you've saved a new setting, it's stored in the database. Pressing + cancel after that will not undo your save action. +
+
+ + + + + + + + +
+ Audit Actions per role +
+ The list of existing audit actions set for the select role. +
+ + + + + + + + + + + + + + + + + + + + + + + +

Role  + +
+ + +
Audit actions 
+
+ +
  +
+     + +
 Save action was + succesful!
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/ManageAuditActionsPerRole.aspx.cs b/GUI/Admin/ManageAuditActionsPerRole.aspx.cs new file mode 100644 index 0000000..f51b20d --- /dev/null +++ b/GUI/Admin/ManageAuditActionsPerRole.aspx.cs @@ -0,0 +1,167 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using System.Collections.Generic; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the ManageAditActionsPerRole form. + /// + public partial class ManageAuditActionsPerRole : System.Web.UI.Page + { + private int _roleID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _roleID = 0; + + if(!Page.IsPostBack) + { + // Get all roles + RoleCollection roles = SecurityGuiHelper.GetAllRoles(); + + cbxRoles.DataSource = roles; + cbxRoles.DataTextField = "RoleDescription"; + cbxRoles.DataValueField = "RoleID"; + cbxRoles.DataBind(); + + if(cbxRoles.Items.Count > 0) + { + cbxRoles.Items[0].Selected = true; + _roleID = HnDGeneralUtils.TryConvertToInt(cbxRoles.SelectedItem.Value); + } + + // get the audit actions + AuditActionCollection auditActions = SecurityGuiHelper.GetAllAuditActions(); + + cblAuditActions.DataSource = auditActions; + cblAuditActions.DataTextField = "AuditActionDescription"; + cblAuditActions.DataValueField = "AuditActionID"; + cblAuditActions.DataBind(); + + // Reflect action rights for current selected forum for this role + ReflectCurrentAuditActions(); + } + else + { + _roleID = HnDGeneralUtils.TryConvertToInt(cbxRoles.SelectedItem.Value); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.cbxRoles.SelectedIndexChanged += new System.EventHandler(this.cbxRoles_SelectedIndexChanged); + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + + /// + /// Reads all audit actions for the current selected role and shows these settings in the form + /// + private void ReflectCurrentAuditActions() + { + RoleAuditActionCollection roleAuditActions = SecurityGuiHelper.GetAllAuditActionsForRole(_roleID); + + // check the checkboxes in the cblAuditActions list if the value matches an object in the collection + foreach(RoleAuditActionEntity roleAuditAction in roleAuditActions) + { + cblAuditActions.Items.FindByValue(roleAuditAction.AuditActionID.ToString()).Selected=true; + } + } + + private void cbxRoles_SelectedIndexChanged(object sender, System.EventArgs e) + { + cblAuditActions.ClearSelection(); + ReflectCurrentAuditActions(); + phSaveResult.Visible=false; + } + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + // read checked audit actions + List checkedAuditActions = new List(); + + for(int i=0;i + + + + + + +
+

Manage forum rights

+ Below you can configure the forum right definitions for the role <%=base.RoleDescription%>. You first select a forum, then + you check / uncheck every action right to set the rights for this role and the forum selected. When you are done, click Save to + save the definition or click Cancel to go back to the role list. Once you've saved a new setting, it's stored in the database. Pressing + cancel after that will not undo your save action. +

+ You can only set a subset of all + the available rights to a role here, since only the action rights for forums are available here. Modify the role itself to set + system rights. All users in the role will inherit the rights you set when their next session begins. +
+
+ + + + + + + + +
+ Action rights per forum for role <%=base.RoleDescription%> +
+  The list of existing action rights set for the given role per forum. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Section  + +
Forum  + +
+ + +
Forum rights 
+
+ +
  +
+     + +
 Save action was succesful!
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/ManageForumRights.aspx.cs b/GUI/Admin/ManageForumRights.aspx.cs new file mode 100644 index 0000000..fb4c622 --- /dev/null +++ b/GUI/Admin/ManageForumRights.aspx.cs @@ -0,0 +1,225 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using System.Collections.Generic; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// code behind file for the ManageForumRights form + /// + public partial class ManageForumRights : System.Web.UI.Page + { + private string _roleDescription; + private int _roleID, _forumID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + bool hasAccess = SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement); + if(!hasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _roleID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["RoleID"]); + + if(!Page.IsPostBack) + { + // get the role and show the description + RoleEntity role = SecurityGuiHelper.GetRole(_roleID); + if(!role.IsNew) + { + _roleDescription = role.RoleDescription; + } + + // store in viewstate. + ViewState.Add("sRoleDescription", _roleDescription); + + // Get all sections, which do have a forum. + DataView sections = SectionGuiHelper.GetAllSectionsWStatisticsAsDataView(true); + + cbxSections.DataSource = sections; + cbxSections.DataTextField = "SectionName"; + cbxSections.DataValueField = "SectionID"; + cbxSections.DataBind(); + + if(cbxSections.Items.Count > 0) + { + cbxSections.Items[0].Selected=true; + } + + FillForumList(); + + // get the forum action rights + ActionRightCollection actionRights = SecurityGuiHelper.GetAllActionRightsApplybleToAForum(); + + cblForumRights.DataSource = actionRights; + cblForumRights.DataTextField = "ActionRightDescription"; + cblForumRights.DataValueField = "ActionRightID"; + cblForumRights.DataBind(); + + // Reflect action rights for current selected forum for this role + ReflectCurrentActionRights(); + } + else + { + // read role description from viewstate + _roleDescription = ViewState["sRoleDescription"].ToString(); + _forumID = HnDGeneralUtils.TryConvertToInt(cbxForums.SelectedItem.Value); + } + } + + + /// + /// Reads all actionrights for the current selected forum and shows these settings in the form + /// + private void ReflectCurrentActionRights() + { + ForumRoleForumActionRightCollection actionRights = SecurityGuiHelper.GetForumActionRightRolesFoForumRole(_roleID, _forumID); + + foreach(ForumRoleForumActionRightEntity currentEntity in actionRights) + { + cblForumRights.Items.FindByValue(currentEntity.ActionRightID.ToString()).Selected=true; + } + } + + + /// + /// Fills in the forum list based on the selected Section in cbxSections + /// + private void FillForumList() + { + // clear list first + cbxForums.Items.Clear(); + + int currentSectionID = Convert.ToInt32(cbxSections.SelectedItem.Value); + ForumCollection forums = ForumGuiHelper.GetAllForumsInSection(currentSectionID); + + cbxForums.DataSource = forums; + cbxForums.DataTextField = "ForumName"; + cbxForums.DataValueField = "ForumID"; + cbxForums.DataBind(); + + cbxForums.Items[0].Selected=true; + _forumID = Convert.ToInt32(cbxForums.SelectedItem.Value); + } + + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.cbxSections.SelectedIndexChanged += new System.EventHandler(this.cbxSections_SelectedIndexChanged); + this.cbxForums.SelectedIndexChanged += new System.EventHandler(this.cbxForums_SelectedIndexChanged); + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void cbxSections_SelectedIndexChanged(object sender, System.EventArgs e) + { + FillForumList(); + cblForumRights.ClearSelection(); + ReflectCurrentActionRights(); + phSaveResult.Visible=false; + } + + private void cbxForums_SelectedIndexChanged(object sender, System.EventArgs e) + { + cblForumRights.ClearSelection(); + ReflectCurrentActionRights(); + phSaveResult.Visible=false; + } + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + // read checked action rights + List checkedActionRightIDs = new List(); + + for(int i=0;i + /// Gets the role description of the active role. + /// + /// The role description. + protected string RoleDescription + { + get { return _roleDescription; } + } + #endregion + } +} diff --git a/GUI/Admin/ManageIPBans.aspx b/GUI/Admin/ManageIPBans.aspx new file mode 100644 index 0000000..0002ee6 --- /dev/null +++ b/GUI/Admin/ManageIPBans.aspx @@ -0,0 +1,165 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ManageIPBans.aspx.cs" Inherits="SD.HnD.GUI.Admin.ManageIPBans" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Manage IP bans"%> +<%@ Register Assembly="SD.LLBLGen.Pro.ORMSupportClasses.NET20" Namespace="SD.LLBLGen.Pro.ORMSupportClasses" TagPrefix="llblgenpro" %> + + + + + + + + + +
+

Manage IP bans

+ The form below allows you to manage the IP bans currently defined. The form allows you to add, edit and remove IP bans. IP bans are bans on an + IP range. An IP number has 4 segments: aaa.bbb.ccc.ddd. By specifying a range, which can be 8, 16, 24 or 32 for the significant bits in the + IP segments specified, you are able to specify how IP addresses are matched against the set IP ban.

+ Example: you set as IP ban: 1.2.3.4/24, where '24' is the range. When a user with IP address 1.2.3.5 tries to connect to the website, his IP address + matches with this IP ban, as the range is 24, i.e. the first 3 segments, and thus the IP address matches the IP ban if the first 3 segments are the same, + which is the case: 1.2.3. Would the user have the IP address: 2.2.3.4, it wouldn't be a match, as 2.2.3 isn't equal to 1.2.3. +

+ The Switch view button allows you to switch between insert and update view of the formview. When you select a row in the grid, you are able to + either edit it in the formview below it, which is automatically switched to update view, or you're able to delete the row via the Delete selected button. + This button is only visible if a row is selected and the IP ban can be deleted. +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+ + + Edit selected item
+ + + + + + + + + + + + + +
+ IP Address + . + . + . + +
+ Range + + + + + + +
+ Reason + +
+
+ + + + +
+ + Insert new IP ban
+ + + + + + + + + + + + + +
+ IP Address + . + . + . + +
+ Range + + + + + + +
+ Reason + +
+
+ + + + +
+ + Selected Item:

+ IPSegment1: +
+ IPSegment2: +
+ IPSegment3: +
+ IPSegment4: +
+ Range: +
+ + + + + + +
+
+
\ No newline at end of file diff --git a/GUI/Admin/ManageIPBans.aspx.cs b/GUI/Admin/ManageIPBans.aspx.cs new file mode 100644 index 0000000..39d7944 --- /dev/null +++ b/GUI/Admin/ManageIPBans.aspx.cs @@ -0,0 +1,134 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.GUI; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind for the form to manage IP bans. + /// + public partial class ManageIPBans : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if(!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx", true); + } + + // Check if the user has the right systemright + bool userHasAccess = SessionAdapter.HasSystemActionRight(ActionRights.UserManagement); + if(!userHasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx", true); + } + + // set these form variables to their required values, so the InsertParameters of the datasource control can pick them up when a new ip ban + // entity is inserted. + _userID.Value = SessionAdapter.GetUserID().ToString(); + _currentDate.Value = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"); + } + + + /// + /// Handles the PerformGetDbCount event of the _ipBanDS control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _ipBanDS_PerformGetDbCount(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformGetDbCountEventArgs e) + { + e.DbCount = SecurityGuiHelper.GetTotalIPBanCount(); + } + + + /// + /// Handles the PerformSelect event of the _ipBanDS control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _ipBanDS_PerformSelect(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs e) + { + // fetch the page requested, using a BL method. We'll receive a collection from the BL method and will set the collection of the control to the + // collection we'll receive. Specify that the user entity is prefetched into the IPBan entity. + _ipBanDS.EntityCollection = SecurityGuiHelper.GetAllIPBans(e.PageNumber, e.PageSize, true); + } + + + /// + /// Handles the PerformWork event of the _ipBanDS control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _ipBanDS_PerformWork(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformWorkEventArgs e) + { + // the event args contain the UnitOfWork to persist. Pass it on to the BL method + SecurityManager.PersistIPBanUnitOfWork(e.Uow); + + // invalidate cache + CacheManager.InvalidateCachedItem(CacheKeys.AllIPBans); + } + + + protected void _switchViewButton_Click(object sender, EventArgs e) + { + switch(_ipBanFormView.CurrentMode) + { + case FormViewMode.Edit: + _ipBanFormView.ChangeMode(FormViewMode.Insert); + break; + case FormViewMode.Insert: + _ipBanFormView.ChangeMode(FormViewMode.Edit); + break; + } + } + + protected void _deleteSelectedButton_Click(object sender, EventArgs e) + { + int index = _ipBansGrid.SelectedIndex; + if(index < 0) + { + return; + } + _ipBansGrid.DeleteRow(index); + } + + protected void _ipBansGrid_SelectedIndexChanged(object sender, EventArgs e) + { + _ipBanFormView.PageIndex = _ipBansGrid.SelectedIndex; + _deleteSelectedButton.Visible = (_ipBansGrid.SelectedIndex >= 0); + } + } +} \ No newline at end of file diff --git a/GUI/Admin/ManageRoleForumRights.aspx b/GUI/Admin/ManageRoleForumRights.aspx new file mode 100644 index 0000000..8fe5b5c --- /dev/null +++ b/GUI/Admin/ManageRoleForumRights.aspx @@ -0,0 +1,61 @@ +<%@ Page language="c#" CodeFile="ManageRoleForumRights.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ManageRoleForumRights" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Manage Role Forum Rights"%> + + + + + + +
+

Manage Role Forum Rights

+ Below you'll find all existing roles in the system. Click the Manage button next to the role which forum rights you want to manage. +
+
+ + + + + + + + +
+ Existing roles +
+ The list of existing roles in the forum system. +
+ + + + + + + + + + + + + + + + + + + + +
Role descriptionAction
+ <%#Eval("RoleDescription")%>
+ This role is used for anonymous users. + This role is assigned to new users. +
+ +
+ <%#Eval("RoleDescription")%>
+ This role is used for anonymous users. + This role is assigned to new users. +
+ +
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/ManageRoleForumRights.aspx.cs b/GUI/Admin/ManageRoleForumRights.aspx.cs new file mode 100644 index 0000000..cafe976 --- /dev/null +++ b/GUI/Admin/ManageRoleForumRights.aspx.cs @@ -0,0 +1,107 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the ManageRoleForumRights form. + /// + public partial class ManageRoleForumRights : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // bind the Roles repeater to a dataview with all sections. + DataView rolesWithStatistics = SecurityGuiHelper.GetAllRolesWithStatisticsAsDataView(); + + rpRoles.DataSource = rolesWithStatistics; + rpRoles.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + this.rpRoles.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.rpRoles_ItemCommand); + } + #endregion + + /// + /// handles all click events of all the buttons generated in the repeater control. + /// + /// + /// Contains all information needed to determine which button was pressed plus which action + /// to take. + /// + private void rpRoles_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e) + { + // Check which button was pressed and redirect to the page in question. + switch(e.CommandName) + { + case "Manage": + // user pressed a manage button. + Response.Redirect("ManageForumRights.aspx?RoleID=" + e.CommandArgument); + break; + } + } + } +} diff --git a/GUI/Admin/ManageSupportQueues.aspx b/GUI/Admin/ManageSupportQueues.aspx new file mode 100644 index 0000000..5740c12 --- /dev/null +++ b/GUI/Admin/ManageSupportQueues.aspx @@ -0,0 +1,136 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ManageSupportQueues.aspx.cs" Inherits="SD.HnD.GUI.Admin.ManageSupportQueues" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Manage Support Queues"%> +<%@ Register Assembly="SD.LLBLGen.Pro.ORMSupportClasses.NET20" Namespace="SD.LLBLGen.Pro.ORMSupportClasses" TagPrefix="llblgenpro" %> + + + + + + +
+

Manage support queues

+ The form below allows you to manage support queues in the forum system: you can add new ones and edit and delete existing queues. You can only + manage the support queue definitions, not their contents. If you delete a support queue, all threads inside that queue will be made queue-less. +

+ The Switch view button allows you to switch between insert and update view of the formview. When you select a row in the grid, you are able to + either edit it in the formview below it, which is automatically switched to update view, or you're able to delete the row via the Delete selected button. + This button is only visible if a row is selected and the IP ban can be deleted. +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ + + +
+
+ + + Edit selected item
+ + + + + + + + + + + + + +
+ Queue name + +
+ Description + +
+ Order no + + +
+
+ + + + +
+ + Insert new support queue
+ + + + + + + + + + + + + +
+ Queue name + +
+ Description + +
+ Order no + + + +
+
+ + + + +
+
+ +
\ No newline at end of file diff --git a/GUI/Admin/ManageSupportQueues.aspx.cs b/GUI/Admin/ManageSupportQueues.aspx.cs new file mode 100644 index 0000000..3bf995e --- /dev/null +++ b/GUI/Admin/ManageSupportQueues.aspx.cs @@ -0,0 +1,129 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the ManageSupportQueues form. + /// + public partial class ManageSupportQueues : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if(!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx", true); + } + + // Check if the user has the right systemright + bool userHasAccess = SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement); + if(!userHasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx", true); + } + } + + + /// + /// Handles the PerformSelect event of the _supportQueueDS control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _supportQueueDS_PerformSelect(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs e) + { + _supportQueueDS.EntityCollection = SupportQueueGuiHelper.GetAllSupportQueues(); + } + + + /// + /// Handles the PerformWork event of the _supportQueueDS control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _supportQueueDS_PerformWork(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformWorkEventArgs e) + { + SupportQueueManager.PersistSupportQueueUnitOfWork(e.Uow); + + // invalidate cache + CacheManager.InvalidateCachedItem(CacheKeys.AllSupportQueues); + } + + + /// + /// Handles the Click event of the _switchViewButton control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _switchViewButton_Click(object sender, EventArgs e) + { + switch(_supportQueueFormView.CurrentMode) + { + case FormViewMode.Edit: + _supportQueueFormView.ChangeMode(FormViewMode.Insert); + break; + case FormViewMode.Insert: + _supportQueueFormView.ChangeMode(FormViewMode.Edit); + break; + } + } + + /// + /// Handles the Click event of the _deleteSelectedButton control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _deleteSelectedButton_Click(object sender, EventArgs e) + { + int index = _supportQueuesGrid.SelectedIndex; + if(index < 0) + { + return; + } + _supportQueuesGrid.DeleteRow(index); + } + + + /// + /// Handles the SelectedIndexChanged event of the _supportQueuesGrid control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _supportQueuesGrid_SelectedIndexChanged(object sender, EventArgs e) + { + _supportQueueFormView.PageIndex = _supportQueuesGrid.SelectedIndex; + _deleteSelectedButton.Visible = (_supportQueuesGrid.SelectedIndex >= 0); + } + } +} \ No newline at end of file diff --git a/GUI/Admin/ManageUsersInRole.aspx b/GUI/Admin/ManageUsersInRole.aspx new file mode 100644 index 0000000..f41caf0 --- /dev/null +++ b/GUI/Admin/ManageUsersInRole.aspx @@ -0,0 +1,71 @@ +<%@ Page language="c#" CodeFile="ManageUsersInRole.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ManageUsersInRole" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Manage users in role"%> + + + + + + +
+

Manage users in role.

+ Below you'll find all existing roles in the system. Select the role which users you want to administrate. When your system has a lot of users, + the administration pages for roles with a lot of users can be huge and therefor somewhat slow. +
+

+ + + + + + + + +
+ Existing roles +
+ The list of existing roles in the forum system. +
+ + + + + + + + + + + + + + + + + + + + + + + +
Role description# UsersAction
+ <%#Eval("RoleDescription")%>
+ This role is used for anonymous users. + This role is assigned to new users. +
+ + +    + +
+ <%#Eval("RoleDescription")%>
+ This role is used for anonymous users. + This role is assigned to new users. +
+ + +    + +
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/ManageUsersInRole.aspx.cs b/GUI/Admin/ManageUsersInRole.aspx.cs new file mode 100644 index 0000000..0444ffb --- /dev/null +++ b/GUI/Admin/ManageUsersInRole.aspx.cs @@ -0,0 +1,113 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the ManageUsersInRole form. + /// + public partial class ManageUsersInRole : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // bind the Roles repeater to a dataview with all roles. + DataView dvRoles = SecurityGuiHelper.GetAllRolesWithStatisticsAsDataView(); + + rpRoles.DataSource = dvRoles; + rpRoles.DataBind(); + } + } + + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + this.rpRoles.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.rpRoles_ItemCommand); + } + #endregion + + + /// + /// handles all click events of all the buttons generated in the repeater control. + /// + /// + /// Contains all information needed to determine which button was pressed plus which action + /// to take. + /// + private void rpRoles_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e) + { + // Check which button was pressed and redirect to the page in question. + switch(e.CommandName) + { + case "AddUsersToRole": + // user pressed an add users button. + Response.Redirect("AddUsersToRole.aspx?RoleID=" + e.CommandArgument); + break; + case "RemoveUsersFromRole": + // user pressed a remove users button. + Response.Redirect("RemoveUsersFromRole.aspx?RoleID=" + e.CommandArgument); + break; + } + } + } +} diff --git a/GUI/Admin/ModifyDeleteForum.aspx b/GUI/Admin/ModifyDeleteForum.aspx new file mode 100644 index 0000000..f1a5278 --- /dev/null +++ b/GUI/Admin/ModifyDeleteForum.aspx @@ -0,0 +1,80 @@ +<%@ Page language="c#" CodeFile="ModifyDeleteForum.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ModifyDeleteForum" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Modify / Delete a forum"%> + + + + + + +
+

Modify / delete a forum

+ Below you'll find all existing forums in the system, including the section's they're in. Modifying a forum means you can change the name, the + description and the section location of the forum. Deleting a forum means that the forum, all its threads and all the messages in those threads, + including the history records are deleted from the database. This action is irreversable and most of the time unnecessary. If you want to hide + a forum, you can simply remove the Access Forum right for all roles on the particular forum and the forum is hidden automatically. If you hide a forum + it's often wise to remove all rights for all roles from the forum, so no-one can take actions on the forum through the system. +
+

+ + + + + + + + +
+ Existing forums +
+ The list of existing forums in the forum system, including the sections they're in. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Forum nameLocated in sectionOrder no. 
+ <%#Eval("ForumName") %>
+ <%#Eval("ForumDescription")%> +
+ <%#Eval("SectionName") %>
+
+ <%#Eval("ForumOrderNo") %>
+
+    + +
+ <%#Eval("ForumName") %>
+ <%#Eval("ForumDescription")%> +
+ <%#Eval("SectionName") %>
+
+ <%#Eval("ForumOrderNo") %>
+
+    + +
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/ModifyDeleteForum.aspx.cs b/GUI/Admin/ModifyDeleteForum.aspx.cs new file mode 100644 index 0000000..ad90b91 --- /dev/null +++ b/GUI/Admin/ModifyDeleteForum.aspx.cs @@ -0,0 +1,111 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.TypedListClasses; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the ModifyDeleteForum form. + /// + public partial class ModifyDeleteForum : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // Read all the current existing forums and their section names. + ForumsWithSectionNameTypedList forumsWithSectionNames = ForumGuiHelper.GetAllForumsWithSectionNames(); + rpForums.DataSource = forumsWithSectionNames; + rpForums.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + this.rpForums.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.rpForums_ItemCommand); + } + #endregion + + /// + /// handles all click events of all the buttons generated in the repeater control. + /// + /// + /// Contains all information needed to determine which button was pressed plus which action + /// to take. + /// + private void rpForums_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e) + { + // Check which button was pressed and redirect to the page in question. + switch(e.CommandName) + { + case "Modify": + // user pressed a modify button. + Response.Redirect("ModifyForum.aspx?ForumID=" + e.CommandArgument); + break; + case "Delete": + // user pressed a delete button. + Response.Redirect("DeleteForum.aspx?ForumID=" + e.CommandArgument); + break; + } + } + } +} diff --git a/GUI/Admin/ModifyDeleteRole.aspx b/GUI/Admin/ModifyDeleteRole.aspx new file mode 100644 index 0000000..08e147a --- /dev/null +++ b/GUI/Admin/ModifyDeleteRole.aspx @@ -0,0 +1,80 @@ +<%@ Page language="c#" CodeFile="ModifyDeleteRole.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ModifyDeleteRole" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Modify / Delete a role"%> + + + + + + +
+

Modify / delete a role

+ Below you'll find all existing roles in the system. Modifying a role means that you can change the description of the role plus change + all system rights assigned to that role. Deleting a role means you delete that role, all user-role assignments and all rights assigned to + the role from the system. Be aware of the fact that if you remove all the roles which have one or more system administration rights, you can not + administrate the system when you re-login. You can't delete the role for anonymous users (users who visit the forum system but are not logged in) + or the role which is default assigned to new users.

+ You can change which roles are used for anonymous users or for new users in + Modify system parameters, if you have the proper access rights for that. +
+

+ + + + + + + + +
+ Existing roles +
+ The list of existing roles in the forum system. +
+ + + + + + + + + + + + + + + + + + + + + + + +
Role description# UsersAction
+ <%# Eval("RoleDescription")%>
+ This role is used for anonymous users. + This role is assigned to new users. +
+ + +    + +
+ <%#Eval("RoleDescription")%>
+ This role is used for anonymous users. + This role is assigned to new users. +
+ + +    + +
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/ModifyDeleteRole.aspx.cs b/GUI/Admin/ModifyDeleteRole.aspx.cs new file mode 100644 index 0000000..5b8d863 --- /dev/null +++ b/GUI/Admin/ModifyDeleteRole.aspx.cs @@ -0,0 +1,111 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the ModifyDeleteRole form. + /// + public partial class ModifyDeleteRole : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // bind the Roles repeater to a dataview with all sections. + DataView roles = SecurityGuiHelper.GetAllRolesWithStatisticsAsDataView(); + + rpRoles.DataSource = roles; + rpRoles.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + this.rpRoles.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.rpRoles_ItemCommand); + } + #endregion + + /// + /// handles all click events of all the buttons generated in the repeater control. + /// + /// + /// Contains all information needed to determine which button was pressed plus which action + /// to take. + /// + private void rpRoles_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e) + { + // Check which button was pressed and redirect to the page in question. + switch(e.CommandName) + { + case "Modify": + // user pressed a modify button. + Response.Redirect("ModifyRole.aspx?RoleID=" + e.CommandArgument); + break; + case "Delete": + // user pressed a delete button. + Response.Redirect("DeleteRole.aspx?RoleID=" + e.CommandArgument); + break; + } + } + } +} diff --git a/GUI/Admin/ModifyDeleteSection.aspx b/GUI/Admin/ModifyDeleteSection.aspx new file mode 100644 index 0000000..52bb159 --- /dev/null +++ b/GUI/Admin/ModifyDeleteSection.aspx @@ -0,0 +1,76 @@ +<%@ Page language="c#" CodeFile="ModifyDeleteSection.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ModifyDeleteSection" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Modify / Delete a section"%> + + + + + + +
+

Modify / delete a section

+ Below you'll find all existing sections in the system. Modifying a section means you can change the name and the + description. You can only delete a section if there are no forums in that section. The sections you can delete have a delete-button, others lack that + button. +
+

+ + + + + + + + +
+ Existing sections +
+ The list of existing sections in the forum system. +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Section NameSort-order no. 
+ <%#Eval("SectionName") %>
+ <%#Eval("SectionDescription")%> +
+ <%#Eval("OrderNo") %>
+
+    + +
+ <%#Eval("SectionName") %>
+ <%#Eval("SectionDescription")%> +
+ <%#Eval("OrderNo") %>
+
+    + +
+ +
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/ModifyDeleteSection.aspx.cs b/GUI/Admin/ModifyDeleteSection.aspx.cs new file mode 100644 index 0000000..6712538 --- /dev/null +++ b/GUI/Admin/ModifyDeleteSection.aspx.cs @@ -0,0 +1,113 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; + + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the ModifyDeleteSection form. + /// + public partial class ModifyDeleteSection : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // bind the sections repeater to a dataview with all sections and the amount of forums inside that section. + DataView sections = SectionGuiHelper.GetAllSectionsWStatisticsAsDataView(false); + + rpSections.DataSource = sections; + rpSections.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.rpSections.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.rpSections_ItemCommand); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + + /// + /// handles all click events of all the buttons generated in the repeater control. + /// + /// + /// Contains all information needed to determine which button was pressed plus which action + /// to take. + /// + private void rpSections_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e) + { + // Check which button was pressed and redirect to the page in question. + switch(e.CommandName) + { + case "Modify": + // user pressed a modify button. + Response.Redirect("ModifySection.aspx?SectionID=" + e.CommandArgument); + break; + case "Delete": + // user pressed a delete button. + Response.Redirect("DeleteSection.aspx?SectionID=" + e.CommandArgument); + break; + } + } + } +} diff --git a/GUI/Admin/ModifyForum.aspx b/GUI/Admin/ModifyForum.aspx new file mode 100644 index 0000000..44876d5 --- /dev/null +++ b/GUI/Admin/ModifyForum.aspx @@ -0,0 +1,137 @@ +<%@ Page language="c#" CodeFile="ModifyForum.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ModifyForum" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Modify a forum"%> + + + + + + +
+

Modify a forum

+ Below you'll be able to modify the name, description and location of a forum. When you're done and click Save, the + changes are made instantly and are irreversable. Cancel will bring you back to the previous screen with the + forum listing. +

+ The default support queue is the queue to which threads in the forum are added to if the thread is new, or gets a new message. + Assign only a support queue to a forum if messages in the forum require attention from a special group of users who have queue contents management + access rights. +
+
+ + + + + + + + + + +
+ Modify a forum +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Forum name 
Description  + +
Place in section  + +
Has RSS Feed  + + Warning: Be aware that everyone can see messages posted in this forum via an RSS feed. If you don't want that, don't + enable an RSS feed on this forum +
Default support queue  + + + +
+ Default thread interval  + + + + + + + +
Sort-order no.  + +
Max. # attachments per message  + +
Max. attachment size  + KB +
New thread welcome text 
(optional) 
+ +
+ You can use all normal message UBB tags in this text. All line breaks will be line breaks when the text is shown and + all URLs are automatically converted, please prefix any URL with http:// or https://. The New thread welcome text is shown + when a new thread is started, above the message box. +
  +
+     + +
  +
+ +
+
+
\ No newline at end of file diff --git a/GUI/Admin/ModifyForum.aspx.cs b/GUI/Admin/ModifyForum.aspx.cs new file mode 100644 index 0000000..2ccad2a --- /dev/null +++ b/GUI/Admin/ModifyForum.aspx.cs @@ -0,0 +1,177 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind for the ModifyForum form. + /// + public partial class ModifyForum : System.Web.UI.Page + { + private int _forumID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _forumID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ForumID"]); + + if(!Page.IsPostBack) + { + // read sections for the drop down list. + SectionCollection sections = SectionGuiHelper.GetAllSections(); + cbxSections.DataSource = sections; + cbxSections.DataBind(); + + SupportQueueCollection supportQueues = CacheManager.GetAllSupportQueues(); + cbxSupportQueues.DataSource = supportQueues; + cbxSupportQueues.DataBind(); + + // Load the forum. + ForumEntity forum = ForumGuiHelper.GetForum(_forumID); + if(forum!=null) + { + // forum found + tbxForumDescription.Text = forum.ForumDescription; + tbxForumName.Value = forum.ForumName; + tbxOrderNo.Text = forum.OrderNo.ToString(); + + cbxSections.SelectedValue = forum.SectionID.ToString(); + + if(forum.DefaultSupportQueueID.HasValue) + { + cbxSupportQueues.SelectedValue = forum.DefaultSupportQueueID.Value.ToString(); + } + chkHasRSSFeed.Checked = forum.HasRSSFeed; + cbxThreadListInterval.SelectedValue = forum.DefaultThreadListInterval.ToString(); + tbxMaxAttachmentSize.Text = forum.MaxAttachmentSize.ToString(); + tbxMaxNoOfAttachmentsPerMessage.Text = forum.MaxNoOfAttachmentsPerMessage.ToString(); + + if(forum.NewThreadWelcomeText != null) + { + tbxNewThreadWelcomeText.Text = forum.NewThreadWelcomeText; + } + + } + else + { + // not found + Response.Redirect("Default.aspx",true); + } + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + // store the new data. + if(Page.IsValid) + { + int? supportQueueID = null; + int selectedSupportQueueID = Convert.ToInt32(cbxSupportQueues.SelectedItem.Value); + if( selectedSupportQueueID > 0) + { + supportQueueID = selectedSupportQueueID; + } + + string newThreadWelcomeText = null; + string newThreadWelcomeTextAsHTML = null; + if(tbxNewThreadWelcomeText.Text.Trim().Length > 0) + { + // has specified welcome text, convert to HTML + newThreadWelcomeText = tbxNewThreadWelcomeText.Text.Trim(); + string parserLog, textAsXML; + bool errorsOccured; + newThreadWelcomeTextAsHTML = TextParser.TransformUBBMessageStringToHTML(newThreadWelcomeText, ApplicationAdapter.GetParserData(), + out parserLog, out errorsOccured, out textAsXML); + } + + // page is valid, store the forum. + if(ForumManager.ModifyForum(_forumID, HnDGeneralUtils.TryConvertToInt(cbxSections.SelectedItem.Value), tbxForumName.Value, + tbxForumDescription.Text, chkHasRSSFeed.Checked, supportQueueID, HnDGeneralUtils.TryConvertToInt(cbxThreadListInterval.SelectedValue), + HnDGeneralUtils.TryConvertToShort(tbxOrderNo.Text), HnDGeneralUtils.TryConvertToInt(tbxMaxAttachmentSize.Text), + HnDGeneralUtils.TryConvertToShort(tbxMaxNoOfAttachmentsPerMessage.Text), newThreadWelcomeText, newThreadWelcomeTextAsHTML)) + { + // went ok! + // invalidate cache + CacheManager.InvalidateCachedItem(CacheManager.ProduceCacheKey(CacheKeys.SingleForum, _forumID)); + // done + Response.Redirect("ModifyDeleteForum.aspx",true); + } + } + } + + private void btnCancel_ServerClick(object sender, System.EventArgs e) + { + // Do nothing + Response.Redirect("ModifyDeleteForum.aspx", true); + } + } +} diff --git a/GUI/Admin/ModifyRole.aspx b/GUI/Admin/ModifyRole.aspx new file mode 100644 index 0000000..b59baac --- /dev/null +++ b/GUI/Admin/ModifyRole.aspx @@ -0,0 +1,71 @@ +<%@ Page language="c#" CodeFile="ModifyRole.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ModifyRole" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Modify a role"%> + + + + + + + +
+

Modify a role

+ Below you'll be able to modify the description of the role, plus assign the role to several system rights. + When you're done and click Save, the changes are made instantly. Cancel will bring you back to the previous screen + with the role listing. Be aware that the role rights are cached for every session, so you will have to start a new session with the + forum system to see the system right changes in effect. +
+
+ + + + + + + + + + +
+ Modify role +
+ Modifies an existing role. +
+ + + + + + + + + + + + + + + + + + + + + +

Role description  + +
+ + +
System rights 
+
+ +
  +
+     + +
  +
+ There was an error saving the role, this can be caused by a role that has the same description. +
+
+
\ No newline at end of file diff --git a/GUI/Admin/ModifyRole.aspx.cs b/GUI/Admin/ModifyRole.aspx.cs new file mode 100644 index 0000000..fa82e69 --- /dev/null +++ b/GUI/Admin/ModifyRole.aspx.cs @@ -0,0 +1,153 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using System.Collections.Generic; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind for the form which allows an administrator to modify a role's properties + /// + public partial class ModifyRole : System.Web.UI.Page + { + private int _roleID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _roleID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["RoleID"]); + + if(!Page.IsPostBack) + { + // get the role and show the description + RoleEntity role = SecurityGuiHelper.GetRole(_roleID); + if(role!=null) + { + tbxRoleDescription.Text = role.RoleDescription; + } + + // get the system rights + ActionRightCollection systemActionRights = SecurityGuiHelper.GetAllSystemActionRights(); + + cblSystemRights.DataSource = systemActionRights; + cblSystemRights.DataTextField = "ActionRightDescription"; + cblSystemRights.DataValueField = "ActionRightID"; + cblSystemRights.DataBind(); + + // get the action rights set for this role + RoleSystemActionRightCollection systemActionRightRoleCombinations = SecurityGuiHelper.GetSystemActionRightRolesForRole(_roleID); + + // check the checkboxes in the cblSystemRights list if the value matches a row in the datatable + foreach(RoleSystemActionRightEntity currentEntity in systemActionRightRoleCombinations) + { + cblSystemRights.Items.FindByValue(currentEntity.ActionRightID.ToString()).Selected=true; + } + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + + private void btnCancel_ServerClick(object sender, System.EventArgs e) + { + // do nothing. + Response.Redirect("ModifyDeleteRole.aspx", true); + } + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + // read checked action rights + List checkedActionRightIDs = new List(); + + for(int i=0;i + + + + + + +
+

Modify a section

+ Below you'll be able to modify the name and description of a section. When you're done and click Save, the + changes are made instantly and are irreversable. Cancel will bring you back to the previous screen with the + section listing. +
+
+ + + + + + + + + + +
+ Modify section +
+ Modifies an existing section to the system immediately. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

 Section name 
 Description  + +
 Sort-order no.  + +
  +
+     + +
  +
+ +
+
+
\ No newline at end of file diff --git a/GUI/Admin/ModifySection.aspx.cs b/GUI/Admin/ModifySection.aspx.cs new file mode 100644 index 0000000..0c15102 --- /dev/null +++ b/GUI/Admin/ModifySection.aspx.cs @@ -0,0 +1,127 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Summary description for ModifySection. + /// + public partial class ModifySection : System.Web.UI.Page + { + protected int _sectionID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _sectionID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["SectionID"]); + + if(!Page.IsPostBack) + { + // Load the section directly from the database and show it in the textboxes + SectionEntity section = SectionGuiHelper.GetSection(_sectionID); + + if(section!=null) + { + // show it + tbxSectionName.Value = section.SectionName; + tbxSectionDescription.Text = section.SectionDescription; + tbxOrderNo.Text = section.OrderNo.ToString(); + } + else + { + // not found + Response.Redirect("Default.aspx",true); + } + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnCancel_ServerClick(object sender, System.EventArgs e) + { + // do nothing, return to sectionlist + Response.Redirect("ModifyDeleteSection.aspx",true); + } + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + // page is valid, store the section. + if(SectionManager.ModifySection(_sectionID, tbxSectionName.Value, tbxSectionDescription.Text, HnDGeneralUtils.TryConvertToShort(tbxOrderNo.Text))) + { + // went ok! + // invalidate cache + CacheManager.InvalidateCachedItem(CacheKeys.AllSections); + // done, redirect. + Response.Redirect("ModifyDeleteSection.aspx",true); + } + } + } + } +} diff --git a/GUI/Admin/ModifySystemParameters.aspx b/GUI/Admin/ModifySystemParameters.aspx new file mode 100644 index 0000000..c44f53d --- /dev/null +++ b/GUI/Admin/ModifySystemParameters.aspx @@ -0,0 +1,103 @@ +<%@ Page language="c#" CodeFile="ModifySystemParameters.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ModifySystemParameters" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Modify system parameters"%> + + + + + + +
+

Modify system parameters

+ Below you can set several system parameters at once. Once you have saved these parameters, the forum system will reload these values into the + application cache so new session will use the new settings immediately. Click Cancel to disgard changes and to go back to the main menu. + Anonymous users are users who are not logged in. The role assigned to them should have only those rights you want anonymous users to have, which + should be rather slim (f.e. only access rights to a subset of your forums). +
+
+ + + + + + + + +
+ System parameter settings +
+ The current values for various system parameters. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Default role for new users  + +
Role for anonymous users  + +
Default user title for new users  + +
Hours threshold for Active Threads  + +
Page size in search results  + +
Min. # of threads to fetch  + +
Min. # of non-sticky visible threads  + +
Send reply notifications  + + + When this option has been enabled, the system will send notification emails to subscribers + who have subscribed to a thread in which a new message was posted. When this option has been disabled, the system won't send + notification emails and users aren't able to subscribe/unsubscribe to threads. + +
  +
+     + +
+
 
+
\ No newline at end of file diff --git a/GUI/Admin/ModifySystemParameters.aspx.cs b/GUI/Admin/ModifySystemParameters.aspx.cs new file mode 100644 index 0000000..dccbf59 --- /dev/null +++ b/GUI/Admin/ModifySystemParameters.aspx.cs @@ -0,0 +1,174 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the ModifySystemParameters form. + /// + public partial class ModifySystemParameters : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(!Page.IsPostBack) + { + // load the data into the dropdown boxes. + RoleCollection allRoles = SecurityGuiHelper.GetAllRoles(); + + cbxDefaultRoleNewUsers.DataSource = allRoles; + cbxDefaultRoleNewUsers.DataTextField = "RoleDescription"; + cbxDefaultRoleNewUsers.DataValueField = "RoleID"; + cbxDefaultRoleNewUsers.DataBind(); + + cbxAnonymousUserRole.DataSource = allRoles; + cbxAnonymousUserRole.DataTextField = "RoleDescription"; + cbxAnonymousUserRole.DataValueField = "RoleID"; + cbxAnonymousUserRole.DataBind(); + + UserTitleCollection userTitles = UserGuiHelper.GetAllUserTitles(); + + cbxDefaultUserTitleNewUsers.DataSource = userTitles; + cbxDefaultUserTitleNewUsers.DataTextField = "UserTitleDescription"; + cbxDefaultUserTitleNewUsers.DataValueField = "UserTitleID"; + cbxDefaultUserTitleNewUsers.DataBind(); + + // preselect the current values of the system parameters. + SystemDataEntity systemData = CacheManager.GetSystemData(); + + cbxDefaultRoleNewUsers.SelectedValue = systemData.DefaultRoleNewUser.ToString(); + cbxAnonymousUserRole.SelectedValue = systemData.AnonymousRole.ToString(); + cbxDefaultUserTitleNewUsers.SelectedValue = systemData.DefaultUserTitleNewUser.ToString(); + + tbxActiveThreadsThreshold.Text = systemData.HoursThresholdForActiveThreads.ToString(); + tbxMinNumberOfNonStickyVisibleThreads.Text = systemData.MinNumberOfNonStickyVisibleThreads.ToString(); + tbxMinNumberOfThreadsToFetch.Text = systemData.MinNumberOfThreadsToFetch.ToString(); + tbxPageSizeInSearchResults.Text = systemData.PageSizeSearchResults.ToString(); + + chkSendReplyNotifications.Checked = systemData.SendReplyNotifications; + + ViewState.Add("ID", systemData.ID); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSave.ServerClick += new System.EventHandler(this.btnSave_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnSave_ServerClick(object sender, System.EventArgs e) + { + // store the new settings in the database, refresh Application Object's cache when succeeded. + int ID = (int)ViewState["ID"]; + + short activeThreadsThreshold = HnDGeneralUtils.TryConvertToShort(tbxActiveThreadsThreshold.Text); + if(activeThreadsThreshold <= 0) + { + activeThreadsThreshold = 48; + } + + short pageSizeSearchResults = HnDGeneralUtils.TryConvertToShort(tbxPageSizeInSearchResults.Text); + if(pageSizeSearchResults <= 0) + { + pageSizeSearchResults = 50; + } + + short minNumberOfThreadsToFetch = HnDGeneralUtils.TryConvertToShort(tbxMinNumberOfThreadsToFetch.Text); + if(minNumberOfThreadsToFetch <= 0) + { + minNumberOfThreadsToFetch = 25; + } + + short minNumberOfNonStickyVisibleThreads = HnDGeneralUtils.TryConvertToShort(tbxMinNumberOfNonStickyVisibleThreads.Text); + if(minNumberOfNonStickyVisibleThreads <= 0) + { + minNumberOfNonStickyVisibleThreads = 5; + } + + bool result = SystemManager.StoreNewSystemSettings(ID, + Convert.ToInt32(cbxDefaultRoleNewUsers.SelectedItem.Value), + Convert.ToInt32(cbxAnonymousUserRole.SelectedItem.Value), + Convert.ToInt32(cbxDefaultUserTitleNewUsers.SelectedItem.Value), activeThreadsThreshold, pageSizeSearchResults, + minNumberOfThreadsToFetch, minNumberOfNonStickyVisibleThreads, chkSendReplyNotifications.Checked); + + if(result) + { + // invalidate cache + CacheManager.InvalidateCachedItem(CacheKeys.SystemData); + } + + // ignore result for now + Response.Redirect("Default.aspx",true); + } + + private void btnCancel_ServerClick(object sender, System.EventArgs e) + { + // do nothing + Response.Redirect("Default.aspx",true); + } + } +} diff --git a/GUI/Admin/ModifyUserProfile.aspx b/GUI/Admin/ModifyUserProfile.aspx new file mode 100644 index 0000000..3b76bc9 --- /dev/null +++ b/GUI/Admin/ModifyUserProfile.aspx @@ -0,0 +1,147 @@ +<%@ Page language="c#" CodeFile="ModifyUserProfile.aspx.cs" AutoEventWireup="true" Inherits="SD.HnD.GUI.Admin.ModifyUserProfile" ValidateRequest="false" + MasterPageFile="~/Admin/AdminMaster.master" title="HnD::Administrate::Modify a user profile"%> +<%@ Register TagPrefix="HnD" TagName="FindUser" Src="FindUser.ascx"%> + + + + + + + +
+ Modify a user profile. +

Below you can change the profile information of a user currently known by the forumsystem. First you've to select the user of whom you want to + modify the profile, and then click Manage profile to manage the profile data. +

+
+
+ +
+ + + + + + +
+ Modify a user profile. +

Below you can change the profile information of a user currently known by the forumsystem. When you're done, click the Update button to make the + changes take effect. If you want to set the password to a new value, specify a new password in the two textboxes for new password, otherwise leave them + empty and the current password will be kept. +

+
+
+ + + + +
+ +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User profile
Registration information. Fields marked with a '*' are mandatory.
Nickname + +
New password + +
New Password
+ For confirmation +
+ + +
Emailaddress * +   + + +

Personal information, which should tell something about the user.
User icon URL
+ (Only 60x60 .jpg and .gif are accepted) +
+ http://
+ +
Date of birth
+ Format: mm/dd/yyyy
+ + +
Occupation
Location
+ e.g.: city, country
Websitehttp://
+ +
Signature
+ You can use several UBB Tags in your signature. Maximum length is 250 characters.
User title + +
  +
+ +
+
+ + + +
+ + + + + +
+ User profile modified succesfully. +
+
+
\ No newline at end of file diff --git a/GUI/Admin/ModifyUserProfile.aspx.cs b/GUI/Admin/ModifyUserProfile.aspx.cs new file mode 100644 index 0000000..89ca499 --- /dev/null +++ b/GUI/Admin/ModifyUserProfile.aspx.cs @@ -0,0 +1,210 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Globalization; + +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; +using System.Collections.Generic; + +namespace SD.HnD.GUI.Admin +{ + /// + /// General class for profile editing by administrators. + /// + public partial class ModifyUserProfile : System.Web.UI.Page + { + private int _selectedUserID; + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if(!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx", true); + } + + // Check if the user has the right systemright + if(!SessionAdapter.HasSystemActionRight(ActionRights.UserManagement)) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx", true); + } + + if(!Page.IsPostBack) + { + + cmbUserTitle.DataSource = UserGuiHelper.GetAllUserTitles(); + cmbUserTitle.DataTextField = "UserTitleDescription"; + cmbUserTitle.DataValueField = "UserTitleID"; + cmbUserTitle.DataBind(); + } + } + + + /// + /// Store the page state into the viewstate. + /// + private void SetViewstate() + { + ViewState.Add("_selectedUserID", _selectedUserID); + } + + + /// + /// Gets the state of the page from the viewstate + /// + private void GetViewState() + { + object value = ViewState["_selectedUserID"]; + if(value != null) + { + _selectedUserID = (int)value; + } + } + + + /// + /// Handler for the selectclicked event of the finduser control. + /// + /// + /// + protected void SelectClickedHandler(object sender, System.EventArgs e) + { + phModifyResult.Visible = false; + + List selectedUserIDs = userFinder.SelectedUserIDs; + if(selectedUserIDs.Count < 0) + { + // nothing selected, return + return; + } + + // just use the first selected user + _selectedUserID = selectedUserIDs[0]; + UserEntity user = UserGuiHelper.GetUser(_selectedUserID); + + if(user == null) + { + // not found + return; + } + + phFindUserArea.Visible = false; + phProfileEditArea.Visible = true; + + // fill in the form with data + lblNickname.Text = string.Format("{0} (UserId: {1})", user.NickName, user.UserID); + tbxEmailAddress.Value = user.EmailAddress; + tbxIconURL.Value = user.IconURL; + if(user.DateOfBirth.HasValue) + { + DateTime dateOfBirth = user.DateOfBirth.Value; + tbxDateOfBirth.Value = dateOfBirth.Month.ToString("0#") + "/" + dateOfBirth.Day.ToString("0#") + "/" + dateOfBirth.Year.ToString("####"); + } + tbxOccupation.Value = user.Occupation; + tbxLocation.Value = user.Location; + tbxWebsite.Value = user.Website; + tbxSignature.Value = user.Signature; + if(user.EmailAddressIsPublic.HasValue) + { + _emailAddressIsVisible.Value = user.EmailAddressIsPublic.Value.ToString().ToLowerInvariant(); + } + else + { + _emailAddressIsVisible.Value = "true"; + } + _defaultNumberOfMessagesPerPage.Value = user.DefaultNumberOfMessagesPerPage.ToString(); + _autoSubscribeToThread.Value = user.AutoSubscribeToThread.ToString().ToLowerInvariant(); + cmbUserTitle.SelectedValue = user.UserTitleID.ToString(); + SetViewstate(); + } + + + protected void btnUpdate_Click(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + GetViewState(); + + // user has filled in the right values, update the user's data. + string nickName = string.Empty; + DateTime? dateOfBirth = null; + string emailAddress = string.Empty; + string iconURL = string.Empty; + string ipNumber = string.Empty; + string location = string.Empty; + string occupation = string.Empty; + string password = string.Empty; + string signature = string.Empty; + string website = string.Empty; + + if(tbxPassword1.Value.Length > 0) + { + password = tbxPassword1.Value; + } + + emailAddress = tbxEmailAddress.Value; + iconURL = tbxIconURL.Value; + + if(tbxDateOfBirth.Value.Length > 0) + { + try + { + dateOfBirth = System.DateTime.Parse(tbxDateOfBirth.Value, CultureInfo.InvariantCulture.DateTimeFormat); + } + catch(FormatException) + { + // format exception, date invalid, ignore, will resolve to default. + } + } + + location = tbxLocation.Value; + occupation = tbxOccupation.Value; + signature = tbxSignature.Value; + website = tbxWebsite.Value; + + bool result = UserManager.UpdateUserProfile(_selectedUserID, dateOfBirth, emailAddress, (_emailAddressIsVisible.Value == "true"), iconURL, location, occupation, password, + signature, website, HnDGeneralUtils.TryConvertToInt(cmbUserTitle.SelectedValue), ApplicationAdapter.GetParserData() + , (_autoSubscribeToThread.Value=="true"), HnDGeneralUtils.TryConvertToShort(_defaultNumberOfMessagesPerPage.Value)); + + if(result) + { + // all ok + phModifyResult.Visible = true; + phFindUserArea.Visible = false; + phProfileEditArea.Visible = false; + } + } + } + } +} diff --git a/GUI/Admin/RemoveUsersFromRole.aspx b/GUI/Admin/RemoveUsersFromRole.aspx new file mode 100644 index 0000000..c752143 --- /dev/null +++ b/GUI/Admin/RemoveUsersFromRole.aspx @@ -0,0 +1,53 @@ +<%@ Page language="c#" CodeFile="RemoveUsersFromRole.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.RemoveUsersFromRole" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::Remove users from role"%> + + + + + + +
+

Remove users from role.

+ Below you'll find all existing users in the system who are currently part of the role <%=base.RoleDescription%>. + All users are shown, also the users who are banned.

+ You can select multiple users by holding down control and left clicking nicknames. When you're done, click Remove user(s) to remove the + selected users from the role or click Cancel to go back to the role list. The users are not removed from the system, only removed from the role. +
+

+ + + + + + + + + + +
+ Select users to remove from the role <%=base.RoleDescription%> +
+ Removes all selected users from the given role. Hold down the control (ctrl) key while left-clicking + the names to multi-select users. +
+ + + + + + + + + + + + +

Users in role  + +
  +
+     + +
+
+
\ No newline at end of file diff --git a/GUI/Admin/RemoveUsersFromRole.aspx.cs b/GUI/Admin/RemoveUsersFromRole.aspx.cs new file mode 100644 index 0000000..3906819 --- /dev/null +++ b/GUI/Admin/RemoveUsersFromRole.aspx.cs @@ -0,0 +1,152 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using System.Collections.Generic; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind page for the form which allows an administrator to remove users from a given role. + /// + public partial class RemoveUsersFromRole : System.Web.UI.Page + { + #region Class Member Declarations + private string _roleDescription; + private int _roleID; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + bool hasAccess = SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement); + if(!hasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + _roleID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["RoleID"]); + + if(!Page.IsPostBack) + { + // Get Role + RoleEntity role = SecurityGuiHelper.GetRole(_roleID); + if(role != null) + { + _roleDescription = role.RoleDescription; + } + else + { + _roleDescription = "Not found"; + } + + // bind the users listbox to an entity collection with all users in the role + UserCollection users = UserGuiHelper.GetAllUsersInRole(_roleID); + lbxUsers.DataSource = users; + lbxUsers.DataTextField = "NickName"; + lbxUsers.DataValueField = "UserID"; + lbxUsers.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnRemoveUsers.ServerClick += new System.EventHandler(this.btnRemoveUsers_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnRemoveUsers_ServerClick(object sender, System.EventArgs e) + { + // Delete all selected users from the role + List userIDsToRemove = new List(); + + for(int i=0;i + /// Gets the role description of the active role. + /// + protected string RoleDescription + { + get { return _roleDescription; } + } + #endregion + } +} diff --git a/GUI/Admin/Reparser.aspx b/GUI/Admin/Reparser.aspx new file mode 100644 index 0000000..cf2d540 --- /dev/null +++ b/GUI/Admin/Reparser.aspx @@ -0,0 +1,46 @@ +<%@ Page language="c#" CodeFile="Reparser.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.Reparser" + MasterPageFile="~/Admin/AdminMaster.master" title="HnD::Administrate::MessageReparser"%> + + + + + + +
+

Message reparser

+ Use this form to re-parse the messages. Use with care.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
 StartDate
 Amount to re-parse (empty = parse all from startdate)
 Generate HTML as well
  +
+ (can take a while) +
  +
+ + +
+
+
\ No newline at end of file diff --git a/GUI/Admin/Reparser.aspx.cs b/GUI/Admin/Reparser.aspx.cs new file mode 100644 index 0000000..be85298 --- /dev/null +++ b/GUI/Admin/Reparser.aspx.cs @@ -0,0 +1,102 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.Utility; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the form to reparse all messages or an interval of messages. + /// + public partial class Reparser : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if(!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx", true); + } + + // Check if the user has the right systemright + bool hasAccess = SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement); + if(!hasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx", true); + } + + if(!Page.IsPostBack) + { + cldStartDate.SelectedDate = DateTime.Now; + cldStartDate.VisibleDate = DateTime.Now; + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnStart.Click += new System.EventHandler(this.btnStart_Click); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnStart_Click(object sender, System.EventArgs e) + { + // start the indexation. Grab the selected properties for the indexer. + + int amountToReparse = HnDGeneralUtils.TryConvertToInt(tbxAmountToReparse.Text.Trim()); + + DateTime startDate = cldStartDate.SelectedDate; + int amountProcessed = MessageManager.ReParseMessages(amountToReparse, startDate, chkRegenerateHTML.Checked, ApplicationAdapter.GetParserData()); + + pnlReparseResults.Visible=true; + lblReparseResults.Text = "Number of messages re-parsed: " + amountProcessed; + } + + } +} diff --git a/GUI/Admin/SendEmail.aspx b/GUI/Admin/SendEmail.aspx new file mode 100644 index 0000000..01b244e --- /dev/null +++ b/GUI/Admin/SendEmail.aspx @@ -0,0 +1,93 @@ +<%@ Page language="c#" CodeFile="SendEmail.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.SendEmail" + MasterPageFile="~/Admin/AdminMaster.master" title="HnD::Administrate::Send email to user(s)" ValidateRequest="false"%> +<%@ Register TagPrefix="HnD" TagName="FindUser" Src="FindUser.ascx"%> + + + + + + +
+

Send an email to user(s).

+ Below you can an email to one or more users. First select the user using the Find Users portion of the form, then + specify the email contents and click Send. The email is send using support AT llblgen.com as from address, is always in plain text and is send + as stated in the textbox. +
+
+ +
+ + + + + + + + + + + +
+ Send email to users +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
To  + +
From  + +
Subject  + +
Message  + +
  +
+     + +
+
  +
+
+ +
+
+
+ + + + + + +
Email sent!
+
+
\ No newline at end of file diff --git a/GUI/Admin/SendEmail.aspx.cs b/GUI/Admin/SendEmail.aspx.cs new file mode 100644 index 0000000..d255b64 --- /dev/null +++ b/GUI/Admin/SendEmail.aspx.cs @@ -0,0 +1,191 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; +using System.Collections.Generic; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Code behind file for the SendEmail form to send an email to one or more users. + /// + public partial class SendEmail : System.Web.UI.Page + { + #region Class Member Declarations + private UserCollection _selectedUsers = new UserCollection(); + #endregion + + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + bool userHasAccess = SessionAdapter.HasSystemActionRight(ActionRights.UserManagement); + if(!userHasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + + if(Page.IsPostBack) + { + GetViewState(); + SetToNames(); + } + else + { + SetViewState(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnPost.Click += new System.EventHandler(this.btnPost_Click); + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + + /// + /// Sets the names for the TO: element of an emailmessage + /// + private void SetToNames() + { + lblToNames.Text=string.Empty; + for (int i = 0; i < _selectedUsers.Count; i++) + { + if(i>0) + { + lblToNames.Text+=", "; + } + lblToNames.Text+=string.Format("{0} ({1})", _selectedUsers[i].EmailAddress, _selectedUsers[i].NickName); + } + } + + /// + /// stores the selected users in the viewstate + /// + private void SetViewState() + { + ViewState.Add("selectedUsers", _selectedUsers); + } + + /// + /// retrieves the selected users from the viewstate. + /// + private void GetViewState() + { + _selectedUsers = (UserCollection)ViewState["selectedUsers"]; + } + + + /// + /// Handler for the selectclicked event of the finduser control. + /// + /// + /// + protected void SelectClickedHandler(object sender, System.EventArgs e) + { + List selectedUserIDs = userFinder.SelectedUserIDs; + phEmailConstruction.Visible = (selectedUserIDs.Count>0); + if(selectedUserIDs.Count <= 0) + { + // nothing selected, return + return; + } + + _selectedUsers = UserGuiHelper.GetAllUsersInRange(selectedUserIDs); + SetViewState(); + SetToNames(); + userFinder.Visible=false; + } + + private void btnPost_Click(object sender, System.EventArgs e) + { + if(!Page.IsValid) + { + return; + } + + string[] toAddresses = new string[_selectedUsers.Count]; + + for (int i = 0; i < _selectedUsers.Count; i++) + { + toAddresses[i] = _selectedUsers[i].EmailAddress; + } + + bool result = HnDGeneralUtils.SendEmail(tbxSubject.Value, tbxMessage.Text, tbxFrom.Value, toAddresses, ApplicationAdapter.GetEmailData(), false); + if(result) + { + phEmailConstruction.Visible=false; + phResult.Visible=true; + } + } + + private void btnCancel_Click(object sender, System.EventArgs e) + { + userFinder.Visible=true; + phEmailConstruction.Visible=false; + phResult.Visible=false; + } + } +} diff --git a/GUI/Admin/ViewAuditInfo.aspx b/GUI/Admin/ViewAuditInfo.aspx new file mode 100644 index 0000000..2cc2a33 --- /dev/null +++ b/GUI/Admin/ViewAuditInfo.aspx @@ -0,0 +1,64 @@ +<%@ Page language="c#" CodeFile="ViewAuditInfo.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Admin.ViewAuditInfo" + MasterPageFile="~/Admin/AdminMaster.master" Title="HnD::Administrate::View Audit Info for user"%> +<%@ Register TagPrefix="HnD" TagName="FindUser" Src="FindUser.ascx"%> + + + + + + +
+

View audit info for user.

+ Below you can view the audit info for a user. First select the user using the Find User portion of the form, then show the user's information. +
+
+ + +
+ + + + + + + + + + + +
+ Audit information for user +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
ActionAudited onAdditional info
+ +
+
+
+
\ No newline at end of file diff --git a/GUI/Admin/ViewAuditInfo.aspx.cs b/GUI/Admin/ViewAuditInfo.aspx.cs new file mode 100644 index 0000000..cf1cca0 --- /dev/null +++ b/GUI/Admin/ViewAuditInfo.aspx.cs @@ -0,0 +1,154 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using System.Collections.Generic; + +namespace SD.HnD.GUI.Admin +{ + /// + /// Shows audit info for the selected user. + /// + public partial class ViewAuditInfo : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // If the user doesn't have any access rights to management stuff, the user should + // be redirected to the default of the global system. + if (!SessionAdapter.HasSystemActionRights()) + { + // doesn't have system rights. redirect. + Response.Redirect("../Default.aspx",true); + } + + // Check if the user has the right systemright + bool userHasAccess = SessionAdapter.HasSystemActionRight(ActionRights.UserManagement); + if(!userHasAccess) + { + // no, redirect to admin default page, since the user HAS access to the admin menu. + Response.Redirect("Default.aspx",true); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + this.rptAudits.ItemDataBound+=new RepeaterItemEventHandler(rptAudits_ItemDataBound); + + } + #endregion + + /// + /// Handler for the selectclicked event of the finduser control. + /// + /// + /// + protected void SelectClickedHandler(object sender, System.EventArgs e) + { + List selectedUserIDs = userFinder.SelectedUserIDs; + if(selectedUserIDs.Count < 0) + { + // nothing selected, return + return; + } + + // just use the first selected user + int selectedUserID = selectedUserIDs[0]; + UserEntity user = UserGuiHelper.GetUser(selectedUserID); + lblUserName.Text = user.NickName; + AuditDataCoreCollection audits = SecurityGuiHelper.GetAllAuditsForUser(selectedUserID); + phAuditInfo.Visible=true; + + rptAudits.DataSource = audits; + rptAudits.DataBind(); + } + + private void rptAudits_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + AuditDataCoreEntity auditCore = (AuditDataCoreEntity)e.Item.DataItem; + Label lblAuditAction = (Label)e.Item.FindControl("lblAuditAction"); + lblAuditAction.Text = ((AuditActions)auditCore.AuditActionID).ToString(); + Label lblAuditDateTime = (Label)e.Item.FindControl("lblAuditDateTime"); + lblAuditDateTime.Text = auditCore.AuditedOn.ToString("dd-MMM-yyyy HH:mm:ss"); + + HyperLink infoLink = (HyperLink)e.Item.FindControl("lnkAdditionalInfoLink"); + + switch((AuditActions)auditCore.AuditActionID) + { + case AuditActions.AuditNewMessage: + case AuditActions.AuditAlteredMessage: + case AuditActions.AuditApproveAttachment: + AuditDataMessageRelatedEntity auditMessageData = auditCore as AuditDataMessageRelatedEntity; + if(auditMessageData!=null) + { + // convert the link into a link to the message in question. + infoLink.Visible=true; + infoLink.NavigateUrl = "../GotoMessage.aspx?ThreadID=" + auditMessageData.Message.ThreadID + "&MessageID=" + auditMessageData.MessageID; + infoLink.Text = "Message in thread: '" + auditMessageData.Message.Thread.Subject + "'"; + } + break; + case AuditActions.AuditEditMemo: + case AuditActions.AuditNewThread: + AuditDataThreadRelatedEntity auditThreadData = auditCore as AuditDataThreadRelatedEntity; + if(auditThreadData!=null) + { + infoLink.Visible=true; + infoLink.NavigateUrl = "../Messages.aspx?ThreadID=" + auditThreadData.ThreadID; + infoLink.Text = "Thread: '" + auditThreadData.Thread.Subject + "'"; + } + break; + case AuditActions.AuditLogin: + break; + } + break; + } + } + } +} diff --git a/GUI/App_Code/ApplicationAdapter.cs b/GUI/App_Code/ApplicationAdapter.cs new file mode 100644 index 0000000..3d4be77 --- /dev/null +++ b/GUI/App_Code/ApplicationAdapter.cs @@ -0,0 +1,426 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.BL; +using SD.HnD.Utility; +using System.Collections; +using System.Collections.Specialized; +using System.Security.Cryptography; +using System.Xml.Xsl; +using System.IO; +using System.Collections.Generic; + + +namespace SD.HnD.GUI +{ + /// + /// ApplicationAdapter is used to access Application-wide variables stored in the HttpApplicationState collection + /// + public static class ApplicationAdapter + { + /// + /// Gets the max amount messages per page. + /// + /// maxAmountMessagesPerPage if available, otherwise 25 + public static int GetMaxAmountMessagesPerPage() + { + if (HttpContext.Current.Application["maxAmountMessagesPerPage"] != null) + { + return (int)HttpContext.Current.Application["maxAmountMessagesPerPage"]; + } + return 25; + } + + /// + /// Gets the default from mail address. + /// + /// defaultFromEmailAddress if available, otherwise an empty string + private static string GetDefaultFromEmailAddress() + { + if (HttpContext.Current.Application["defaultFromEmailAddress"] != null) + { + return HttpContext.Current.Application["defaultFromEmailAddress"].ToString(); + } + return string.Empty; + } + + /// + /// Gets the default to mail address. + /// + /// defaultToEmailAddress if available, otherwise an empty string + private static string GetDefaultToEmailAddress() + { + if (HttpContext.Current.Application["defaultToEmailAddress"] != null) + { + return HttpContext.Current.Application["defaultToEmailAddress"].ToString(); + } + return string.Empty; + } + + /// + /// Gets the email password subject. + /// + /// emailPasswordSubject if available, otherwise an empty string + private static string GetEmailPasswordSubject() + { + if(HttpContext.Current.Application["emailPasswordSubject"] != null) + { + return HttpContext.Current.Application["emailPasswordSubject"].ToString(); + } + return string.Empty; + } + + + /// + /// Gets the email thread notification subject. + /// + /// the threadnodification email subject, or an empty string if not found. + private static string GetEmailThreadNotificationSubject() + { + if(HttpContext.Current.Application["emailThreadNotificationSubject"] != null) + { + return HttpContext.Current.Application["emailThreadNotificationSubject"].ToString(); + } + return string.Empty; + } + + + /// + /// Gets the name of the site. + /// + /// siteName if available, otherwise an empty string + public static string GetSiteName() + { + if (HttpContext.Current.Application["siteName"] != null) + { + return HttpContext.Current.Application["siteName"].ToString(); + } + return string.Empty; + } + + /// + /// Gets the virtual root. + /// + /// virtualRoot if available, otherwise an empty string + public static string GetVirtualRoot() + { + if (HttpContext.Current.Application["virtualRoot"] != null) + { + string toReturn = HttpContext.Current.Application["virtualRoot"].ToString(); + if(!toReturn.EndsWith(@"/")) + { + toReturn += @"/"; + } + return toReturn; + } + return string.Empty; + } + + + /// + /// Gets the data files folder MapPath. + /// + /// the data files folder MapPath if available, otherwise an empty string + public static string GetDataFilesMapPath() + { + if (HttpContext.Current.Application["datafilesMapPath"] != null) + { + return HttpContext.Current.Application["datafilesMapPath"].ToString(); + } + return string.Empty; + } + + + /// + /// Gets an email template file path given the template type from the corresponding enum. + /// + /// the email template file path + public static string GetEmailTemplate(EmailTemplate template) + { + string toReturn = string.Empty; + switch (template) + { + case EmailTemplate.RegistrationReply: + toReturn = (string)HttpContext.Current.Application["registrationReplyMailTemplate"]; + break; + case EmailTemplate.ThreadUpdatedNotification: + toReturn = (string)HttpContext.Current.Application["threadUpdatedNotificationTemplate"]; + break; + } + return toReturn; + } + + + /// + /// Create a DTO of all needed e-mail default data. + /// + /// a dictionary of the following keys (defaultFromEmailAddress, defaultToEmailAddress, defaultSMTPServer, emailPassowrdSubject, siteName, applicationURL) + public static Dictionary GetEmailData() + { + Dictionary emailData = new Dictionary(); + emailData.Add("defaultFromEmailAddress", GetDefaultFromEmailAddress()); + emailData.Add("defaultToEmailAddress", GetDefaultToEmailAddress()); + emailData.Add("emailPasswordSubject", GetEmailPasswordSubject()); + emailData.Add("emailThreadNotificationSubject", GetEmailThreadNotificationSubject()); + emailData.Add("siteName", GetSiteName()); + emailData.Add("applicationURL", "http://" + HttpContext.Current.Request.Url.Host + GetVirtualRoot()); + + return emailData; + } + + + /// + /// Gets the message style. + /// + /// A XslTransform if available, otherwise null + private static XslCompiledTransform GetMessageStyle() + { + if (HttpContext.Current.Application["messageStyle"] != null) + { + return (XslCompiledTransform)HttpContext.Current.Application["messageStyle"]; + } + return null; + } + + /// + /// Gets the signature style. + /// + /// A XslTransform if available, otherwise null + private static XslCompiledTransform GetSignatureStyle() + { + if (HttpContext.Current.Application["signatureStyle"] != null) + { + return (XslCompiledTransform)HttpContext.Current.Application["signatureStyle"]; + } + return null; + } + + /// + /// Create a DTO of all needed e-mail default data. + /// + /// a dictionary of the following keys (grammar, actionTable, gotoTable, messageStyle, signatureStyle) + public static ParserData GetParserData() + { + ParserData data = new ParserData(); + data.MessageStyle = GetMessageStyle(); + data.SignatureStyle = GetSignatureStyle(); + + return data; + } + + /// + /// Gets the noise words. + /// + /// Hashtable of noise words if available, otherwise null + public static Hashtable GetNoiseWords() + { + if (HttpContext.Current.Application["noiseWords"] != null) + { + return (Hashtable)HttpContext.Current.Application["noiseWords"]; + } + return null; + } + + /// + /// Gets the IP ban complain email address. + /// + /// IPBanComplainEmailAddress if available, otherwise string.Empty + public static string GetIPBanComplainEmailAddress() + { + if (HttpContext.Current.Application["IPBanComplainEmailAddress"] != null) + { + return HttpContext.Current.Application["IPBanComplainEmailAddress"].ToString(); + } + return string.Empty; + } + + /// + /// Gets the cache flags. + /// + /// Hashtable of cahce flags if available, otherwise null + public static Hashtable GetCacheFlags() + { + if (HttpContext.Current.Application["cacheFlags"] != null) + { + return (Hashtable)HttpContext.Current.Application["cacheFlags"]; + } + return null; + } + + /// + /// sets the flag for the cached RSS feed for the given forum to false, so the cache will be invalidated for that forum rss feed + /// + /// ID of forum which rss feed to invalidate + public static void InvalidateCachedForumRSS(int forumID) + { + Hashtable cacheFlags = GetCacheFlags(); + + try + { + HttpContext.Current.Application.Lock(); + cacheFlags[forumID] = false; + } + finally + { + HttpContext.Current.Application.UnLock(); + } + } + + + /// + /// Checks if the nickname passed in is among the users which have to be logged out by force. All users which are deleted have to be logged out by force. + /// + /// Name of the nick. + /// true if the user has to be logged out by force, false otherwise. + public static bool UserHasToBeLoggedOutByForce(string nickName) + { + return ((Hashtable)HttpContext.Current.Application["usersToLogoutByForce"]).ContainsKey(nickName); + } + + + /// + /// Adds the user to be logged out by force to the set of usernicknames. + /// + /// Name of the nick. + public static void AddUserToListToBeLoggedOutByForce(string nickName) + { + Hashtable usersToLogOutByForce = (Hashtable)HttpContext.Current.Application["usersToLogoutByForce"]; + if(usersToLogOutByForce.ContainsKey(nickName)) + { + return; + } + try + { + HttpContext.Current.Application.Lock(); + usersToLogOutByForce.Add(nickName, null); + } + finally + { + HttpContext.Current.Application.UnLock(); + } + } + + + /// + /// Removes the user from the list to be logged out by force. + /// + /// Name of the nick. + public static void RemoveUserFromListToBeLoggedOutByForce(string nickName) + { + Hashtable usersToLogOutByForce = (Hashtable)HttpContext.Current.Application["usersToLogoutByForce"]; + if(!usersToLogOutByForce.ContainsKey(nickName)) + { + return; + } + try + { + HttpContext.Current.Application.Lock(); + usersToLogOutByForce.Remove(nickName); + } + finally + { + HttpContext.Current.Application.UnLock(); + } + } + + + /// + /// Loads application wide cached data into the Application Object. This routine + /// is called at startup, when the Application_Start event is thrown. + /// + public static void LoadApplicationObjectCacheData() + { + HttpContext currentHttpContext = HttpContext.Current; + NameValueCollection appSettingsCollection = (NameValueCollection)ConfigurationManager.GetSection("appSettings"); + + // read data from web.config + string defaultFromEmailAddress = appSettingsCollection["DefaultFromEmailAddress"].ToString(); + string defaultToEmailAddress = appSettingsCollection["DefaultToEmailAddress"].ToString(); + string emailPasswordSubject = appSettingsCollection["EmailPasswordSubject"].ToString(); + string emailThreadNotificationSubject = appSettingsCollection["EmailThreadNotificationSubject"].ToString(); + string siteName = appSettingsCollection["SiteName"].ToString(); + string virtualRoot = appSettingsCollection["VirtualRoot"].ToString(); + + string ipBanComplainEmailAddress = appSettingsCollection["IPBanComplainEmailAddress"].ToString(); + int maxAmountMessagesPerPage = Convert.ToInt32(appSettingsCollection["MaxAmountMessagesPerPage"]); + + string datafilesPath = currentHttpContext.Server.MapPath(appSettingsCollection["DatafilesPath"].ToString()); + string ubbMessageTransformXSLPathFilename = appSettingsCollection["UBBMessageTransformXSLPathFilename"].ToString(); + string ubbSignatureTransformXSLPathFilename = appSettingsCollection["UBBSignatureTransformXSLPathFilename"].ToString(); + + // Load XML -> HTML transformation XSL + XslCompiledTransform messageStyle = new XslCompiledTransform(); + XslCompiledTransform signatureStyle = new XslCompiledTransform(); + + messageStyle.Load(Path.Combine(datafilesPath, ubbMessageTransformXSLPathFilename)); + signatureStyle.Load(Path.Combine(datafilesPath, ubbSignatureTransformXSLPathFilename)); + + Hashtable noiseWords = GuiHelper.LoadNoiseWordsIntoHashtable(datafilesPath); + + string registrationReplyMailTemplate = File.ReadAllText(Path.Combine(datafilesPath, "RegistrationReplyMail.template")); + string threadUpdatedNotificationTemplate = File.ReadAllText(Path.Combine(datafilesPath, "ThreadUpdatedNotification.template")); + // add other email templates here. + + // fetch all banned users and store them in the set of users to logout by force. + DataView bannedNicknames = UserGuiHelper.GetAllBannedUserNicknamesAsDataView(); + Hashtable usersToLogoutByForce = new Hashtable(); + foreach(DataRowView row in bannedNicknames) + { + usersToLogoutByForce.Add(row["Nickname"].ToString(), null); + } + + // store them into the application object. + HttpApplicationState applicationState = currentHttpContext.Application; + try + { + applicationState.Lock(); + + applicationState.Add("defaultFromEmailAddress", defaultFromEmailAddress); + applicationState.Add("defaultToEmailAddress", defaultFromEmailAddress); + applicationState.Add("siteName", siteName); + applicationState.Add("virtualRoot", virtualRoot); + applicationState.Add("datafilesMapPath", datafilesPath); + applicationState.Add("emailPasswordSubject", emailPasswordSubject); + applicationState.Add("emailThreadNotificationSubject", emailThreadNotificationSubject); + + applicationState.Add("messageStyle", messageStyle); + applicationState.Add("signatureStyle", signatureStyle); + + applicationState.Add("noiseWords", noiseWords); + applicationState.Add("maxAmountMessagesPerPage", maxAmountMessagesPerPage); + applicationState.Add("IPBanComplainEmailAddress", ipBanComplainEmailAddress); + applicationState.Add("cacheFlags", new Hashtable()); + applicationState.Add("usersToLogoutByForce", usersToLogoutByForce); + applicationState.Add("registrationReplyMailTemplate", registrationReplyMailTemplate); + applicationState.Add("threadUpdatedNotificationTemplate", threadUpdatedNotificationTemplate); + } + finally + { + applicationState.UnLock(); + } + } + } +} diff --git a/GUI/App_Code/CacheManager.cs b/GUI/App_Code/CacheManager.cs new file mode 100644 index 0000000..f2af0a3 --- /dev/null +++ b/GUI/App_Code/CacheManager.cs @@ -0,0 +1,245 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.DAL.CollectionClasses; +using System.Web.Caching; +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using System.Text; +using System.Collections.Generic; +using SD.HnD.DAL.HelperClasses; + +/// +/// Simple Cache manager which forms a central point to obtain / invalidate / store data into the ASP.NET cache object of this CacheManager. +/// +/// This cache is for caching data only, not page output. +public static class CacheManager +{ + /// + /// Gets all sections in a collection from the Cache. If it's not available, the collection with all the section entities is loaded from the DB and + /// added to the cache. + /// + /// A SectionCollection with all SectionEntity instances of the sections of the forum system. This collection has to be threated as + /// a readonly collection with readonly objects + public static SectionCollection GetAllSections() + { + Cache activeCache = HttpRuntime.Cache; + SectionCollection toReturn = (SectionCollection)activeCache[CacheKeys.AllSections]; + if(toReturn == null) + { + // not there, store it. + toReturn = SectionGuiHelper.GetAllSections(); + // just store it in the cache without any dependency, as it's hardly changing. + activeCache.Insert(CacheKeys.AllSections, toReturn); + } + + return toReturn; + } + + + /// + /// Gets the name of the section with the id passed in. This routine will utilize the cache instead of going to the DB for the section. + /// If the sections aren't available, it will load them into the cache first. + /// + /// The section ID. + /// name of the section passed in. + public static string GetSectionName(int sectionID) + { + SectionCollection cachedSections = CacheManager.GetAllSections(); + + // use in-memory filtering. + List matches = cachedSections.FindMatches((SectionFields.SectionID == sectionID)); + + // 0 or 1 matches + if(matches.Count > 0) + { + return cachedSections[matches[0]].SectionName; + } + else + { + return string.Empty; + } + } + + + /// + /// Gets the forum entity with the passed in forumid from the cache. If it's not there, it will be loaded from the db and stored in the cache. + /// + /// The forum ID. + /// ForumEntity instance of the forum with id forumID + /// If forumID isn't found, null is returned. ForumEntity instances are cached indefinitely, until the forum is changed or when a message + /// is added to a thread in the forum. The forum entities are cached per entity to make the per-entity requests for a forum faster. Bulk fetches + /// for forum data isn't using this cache, it's fetching the data directly from the DB. This is ok, forumentity data isn't very volatile + public static ForumEntity GetForum(int forumID) + { + Cache activeCache = HttpRuntime.Cache; + string keyToUse = ProduceCacheKey(CacheKeys.SingleForum, forumID); + ForumEntity toReturn = (ForumEntity)activeCache[keyToUse]; + if(toReturn == null) + { + toReturn = ForumGuiHelper.GetForum(forumID); + if(toReturn != null) + { + // found, cache it + activeCache.Insert(keyToUse, toReturn); + } + } + return toReturn; + } + + + /// + /// Gets the system data entity from the cache. If the entity isn't found in the cache, it's loaded first, stored in the cache and then returned. + /// + /// entity with system data, or null if not found. + public static SystemDataEntity GetSystemData() + { + Cache activeCache = HttpRuntime.Cache; + SystemDataEntity toReturn = (SystemDataEntity)activeCache[CacheKeys.SystemData]; + if(toReturn == null) + { + toReturn = SystemGuiHelper.GetSystemSettings(); + if(toReturn != null) + { + // found, cache it + activeCache.Insert(CacheKeys.SystemData, toReturn); + } + } + return toReturn; + } + + + /// + /// Gets all support queues from the cache. If it's not available, the collection with all the support queue entities is loaded from the DB and + /// added to the cache. + /// + /// A SupportQueueCollection with all supportqueue Entity instances of the support queues of the forum system. This collection has to be threated as + /// a readonly collection with readonly objects + /// + public static SupportQueueCollection GetAllSupportQueues() + { + Cache activeCache = HttpRuntime.Cache; + SupportQueueCollection toReturn = (SupportQueueCollection)activeCache[CacheKeys.AllSupportQueues]; + if(toReturn == null) + { + // not there, store it. + toReturn = SupportQueueGuiHelper.GetAllSupportQueues(); + // just store it in the cache without any dependency, as it's hardly changing. + activeCache.Insert(CacheKeys.AllSupportQueues, toReturn); + } + + return toReturn; + } + + + /// + /// Produces the cache key from the passed in values. This routine will append all values in additionalValues to the baseKey, separated by ':'. + /// + /// The base key. + /// The additional values. + /// ready to use cache key based on the values passed in + public static string ProduceCacheKey(string baseKey, params object[] additionalValues) + { + StringBuilder toReturn = new StringBuilder(baseKey); + foreach(object value in additionalValues) + { + toReturn.AppendFormat(":{0}", value); + } + return toReturn.ToString(); + } + + + /// + /// Invalidates the cached item with the key passed in + /// + /// The key of the item to invalidate. + public static void InvalidateCachedItem(string key) + { + Cache activeCache = HttpRuntime.Cache; + activeCache.Remove(key); + } + + + /// + /// Gets all IP bans cached in the cache. + /// + /// Dictionary with per range (key) a dictionary with all IP addresses as keys, with the segments falling into the range concatenated + /// to eachother with a '.' + public static Dictionary> GetAllIPBans() + { + Cache activeCache = HttpRuntime.Cache; + Dictionary> toReturn = (Dictionary>)activeCache[CacheKeys.AllIPBans]; + if(toReturn == null) + { + // not there, store it. + IPBanCollection allIPBans = SecurityGuiHelper.GetAllIPBans(0, 0, false); + toReturn = new Dictionary>(); + foreach(IPBanEntity currentIPBan in allIPBans) + { + Dictionary ipAddresses = null; + if(!toReturn.TryGetValue(currentIPBan.Range, out ipAddresses)) + { + // not there yet, add + ipAddresses = new Dictionary(); + toReturn.Add(currentIPBan.Range, ipAddresses); + } + + // add ip address with segments in range to ipAddresses' key list. + string key = string.Empty; + switch(currentIPBan.Range) + { + case 8: + key = currentIPBan.IPSegment1.ToString(); + break; + case 16: + key = String.Format("{0}.{1}", currentIPBan.IPSegment1, currentIPBan.IPSegment2); + break; + case 24: + key = String.Format("{0}.{1}.{2}", currentIPBan.IPSegment1, currentIPBan.IPSegment2, currentIPBan.IPSegment3); + break; + case 32: + key = String.Format("{0}.{1}.{2}.{3}", currentIPBan.IPSegment1, currentIPBan.IPSegment2, currentIPBan.IPSegment3, currentIPBan.IPSegment4); + break; + default: + // illegal range, ignore + continue; + } + + if(!ipAddresses.ContainsKey(key)) + { + ipAddresses.Add(key, currentIPBan); + } + } + + // just store it in the cache without any dependency + activeCache.Insert(CacheKeys.AllIPBans, toReturn); + } + + return toReturn; + } +} diff --git a/GUI/App_Code/SessionAdapter.cs b/GUI/App_Code/SessionAdapter.cs new file mode 100644 index 0000000..a370f87 --- /dev/null +++ b/GUI/App_Code/SessionAdapter.cs @@ -0,0 +1,585 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.BL; +using SD.HnD.DAL; +using System.Collections; +using System.Collections.Generic; +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.HelperClasses; + +namespace SD.HnD.GUI +{ + /// + /// SessionAdapter is used to access session objects + /// + public static class SessionAdapter + { + /// + /// Cancels the current Session. + /// + public static void Abandon() + { + HttpContext.Current.Session.Abandon(); + } + + + /// + /// Loads the user and his rights and audits to the session object. + /// + /// The user to be added to the session. + public static void LoadUserSessionData(UserEntity user) + { + // Adds the user object to session + AddUserObject(user); + + ActionRightCollection systemActionRights = SecurityGuiHelper.GetSystemActionRightsForUser(user.UserID); + // add user system rights to the session object + AddSystemActionRights(systemActionRights); + + AuditActionCollection auditActions = SecurityGuiHelper.GetAuditActionsForUser(user.UserID); + // add user audit actions to the session object + AddAuditActions(auditActions); + + ForumRoleForumActionRightCollection forumActionRights = SecurityGuiHelper.GetForumsActionRightsForUser(user.UserID); + // add user forums rights to the session object + AddForumsActionRights(forumActionRights); + + // set the last visit date. + if((user.UserID > 0) && (user.LastVisitedDate.HasValue)) + { + SessionAdapter.AddLastVisitDate(user.LastVisitedDate.Value, true); + } + else + { + SessionAdapter.AddLastVisitDate(DateTime.Now, true); + } + } + + + /// + /// Loads the anonymous user session data. + /// + public static void LoadAnonymousSessionData() + { + ForumRoleForumActionRightCollection forumActionRights = SecurityGuiHelper.GetForumsActionRightsForUser(0); // 0 is the the Anonymous userID. + // add user forums rights to the session object + AddForumsActionRights(forumActionRights); + } + + #region Managing UserEntity Session object + /// + /// Adds the user object to session. + /// If the object already exists, it is overwritten with the new value. + /// + /// The user object to be saved + public static void AddUserObject(UserEntity user) + { + //Adds a new item to the session-state collection. + //If the name parameter refers to an existing session state item, the existing item is overwritten with the specified value. + HttpContext.Current.Session.Add("user", user); + } + + /// + /// Gets the user object from session. + /// + /// User Entity object if found, otherwise returns null + private static UserEntity GetUserObject() + { + if (HttpContext.Current.Session["user"] != null) + { + return (UserEntity)HttpContext.Current.Session["user"]; + } + + return null; + } + + /// + /// Gets the user ID from session. + /// + /// UserID if there is a user object in the session, otherwise returns Zero + public static int GetUserID() + { + UserEntity user = GetUserObject(); + if (user != null) + { + return user.UserID; + } + + return 0; + } + + /// + /// Gets the user title ID. + /// + /// + public static int GetUserTitleID() + { + UserEntity user = GetUserObject(); + if(user != null) + { + return user.UserTitleID; + } + + return 0; + } + + /// + /// Gets user nick name from the session. + /// + /// User nick name + public static string GetUserNickName() + { + UserEntity user = GetUserObject(); + if (user != null) + { + return user.NickName; + } + return string.Empty; + } + + /// + /// Gets the user preference DefaultNumberOfMessagesPerPage for the current user + /// + /// the default # of messages per page as set by this user. + public static int GetUserDefaultNumberOfMessagesPerPage() + { + UserEntity user = GetUserObject(); + if(user != null) + { + int toReturn = user.DefaultNumberOfMessagesPerPage; + if(toReturn <= 0) + { + return ApplicationAdapter.GetMaxAmountMessagesPerPage(); + } + else + { + return toReturn; + } + } + + return ApplicationAdapter.GetMaxAmountMessagesPerPage(); + } + + /// + /// Gets the user preference AutoSubscribeToThread for the current user + /// + /// the user preference if the user wants to subscribe to a thread automatically or not. + public static bool GetUserAutoSubscribeToThread() + { + UserEntity user = GetUserObject(); + if(user != null) + { + return user.AutoSubscribeToThread; + } + + return false; + + } + + #endregion + + #region Managing SystemActionRights Session object + /// + /// Adds the system action rights collection to the session. + /// If the object already exists, it is overwritten with the new value. + /// + /// The action rights. + private static void AddSystemActionRights(ActionRightCollection actionRights) + { + //Adds a new item to the session-state collection. + //If the name parameter refers to an existing session state item, the existing item is overwritten with the specified value. + HttpContext.Current.Session.Add("systemActionRights", actionRights); + } + + /// + /// Gets the system action rights from the session. + /// + /// ActionRightCollection if available otherwise returns null. + private static ActionRightCollection GetSystemActionRights() + { + if (HttpContext.Current.Session["systemActionRights"] != null) + { + return (ActionRightCollection)HttpContext.Current.Session["systemActionRights"]; + } + + return null; + } + + + /// + /// Determines whether the user can administrate the system in one way or the other. + /// + /// true if the user can administrate system, user or security + public static bool CanAdministrate() + { + ActionRightCollection actionRights = GetSystemActionRights(); + if((actionRights == null) || (actionRights.Count <= 0)) + { + return false; + } + // use FindMatches to determine if there are actionrights present which allow administation. + List toFind = new List(); + toFind.Add((int)ActionRights.SystemManagement); + toFind.Add((int)ActionRights.SecurityManagement); + toFind.Add((int)ActionRights.UserManagement); + + return (actionRights.FindMatches((ActionRightFields.ActionRightID == toFind)).Count > 0); + } + + + /// + /// Determines whether there are system action rights in the session. + /// + /// + /// true if system action rights exist in the session; otherwise, false. + /// + public static bool HasSystemActionRights() + { + ActionRightCollection actionRights = GetSystemActionRights(); + if (actionRights != null) + { + return (actionRights.Count > 0); + } + + return false; + } + + /// + /// Checks if the user of the current context(session) has the ability to perform the action right on the system. + /// If this is correct, true is returned, otherwise false. + /// + /// Actionright to check. This is a system action right + /// True if the user of the current context is allowed to perform the action right on the + /// system, false otherwise. + public static bool HasSystemActionRight(ActionRights actionRightID) + { + ActionRightCollection actionRights = GetSystemActionRights(); + if (actionRights != null && actionRights.Count > 0) + { + // use the FindMatches routine to find all entities which match with the filter on the specified actionrightid + return (actionRights.FindMatches((ActionRightFields.ActionRightID == (int)actionRightID)).Count > 0); + } + + return false; + } + #endregion + + #region Managing AuditActions Session object + + /// + /// Adds the audit actions collection to the session. + /// If the object already exists, it is overwritten with the new value. + /// + /// The action rights. + private static void AddAuditActions(AuditActionCollection auditActions) + { + //Adds a new item to the session-state collection. + //If the name parameter refers to an existing session state item, the existing item is overwritten with the specified value. + HttpContext.Current.Session.Add("auditActions", auditActions); + } + + /// + /// Gets the audit actions from the session. + /// + /// AuditActionCollection if available otherwise returns null. + private static AuditActionCollection GetAuditActions() + { + if (HttpContext.Current.Session["auditActions"] != null) + { + return (AuditActionCollection)HttpContext.Current.Session["auditActions"]; + } + return null; + } + + /// + /// Checks if the current user needs auditing for the action specified + /// + /// Action. + /// true if the user needs auditing, otherwise false + public static bool CheckIfNeedsAuditing(AuditActions auditActionID) + { + AuditActionCollection auditActions = GetAuditActions(); + if (auditActions != null && auditActions.Count > 0) + { + // create an ActionRight entity, and forcing the PK value, to avoid fetching it from the database. + AuditActionEntity auditAction = new AuditActionEntity(); + auditAction.Fields[(int)AuditActionFieldIndex.AuditActionID].ForcedCurrentValueWrite((int)auditActionID); + auditAction.IsNew = false; + + return auditActions.Contains(auditAction); + } + + return false; + } + #endregion + + #region Managing ForumsActionRights Session object + /// + /// Adds the forums action rights collection to the session. + /// If the object already exists, it is overwritten with the new value. + /// The user can be in various Roles. Each role has 0 or more actionrights assigned to it for each forum. An action right which can be applied to + /// a forum can be for example 'access forum'. These relations are stored in TF_ForumRoleForumActionRight. The user's session object + /// keeps a list of forum - actionrights tuples so the system can quickly check if the user has a given action right assigned to it for a given forum. + /// It does that by storing for each actionrightID a list of forumIDs the user has that actionrightID applied to it. + /// To check if a user then for example has the access forum right for a given forum is easy: if the + /// user has the access forum right assigned to it via a role, is the forum in the list of forums? if not, the user doesn't have the right for the + /// forum, otherwise s/he has the right. + /// This routine reads forum - actionrights combinations and stores them in the dictionary + /// forumsActionRightsInSession, which is stored in the user's Session object under 'forumsActionRights' + /// which keeps per ActionRightID a list of ForumIDs. + /// Since in general the number of Action Rights will be less than the number of forums, we decided to group forum IDs per each action right. + /// An example: A "Power User" Role, has "Access Forum" Action right for the followoing Forums: 1,3,4 and 8, then in the collection of the + /// action right 'Access forum', the ForumIDs 1, 3, 4, and 8 are placed. + /// + /// The action rights. + private static void AddForumsActionRights(ForumRoleForumActionRightCollection forumsActionRights) + { + // create a dictionary that will be stored in the session + Dictionary> forumsActionRightsInSession = new Dictionary>(); + + // For each forumActionRight returned from the database, which contains a forum-actionright combination, we store it in the structure + // for forum-actionrights, if it's not already present. We only store ActionRightIDs and ForumIDs, as the forum code uses these ids to check if a user + // has a given action right for a given forum, which are also numbers, and storing entities wouldn't make much sense in this case, as it would only + // increase memory usage. + foreach (ForumRoleForumActionRightEntity forumActionRight in forumsActionRights) + { + List forumIDs; + + // check if the dictionary already contains a KeyValuePair with the specified ActionRightID key + if (!forumsActionRightsInSession.TryGetValue(forumActionRight.ActionRightID, out forumIDs)) + { + // if not then add a a KeyValuePair to the dictionary with the specified ActionRightID key + forumIDs = new List(); + forumsActionRightsInSession.Add(forumActionRight.ActionRightID, forumIDs); + } + + // Check if the List of forum IDs associated with the specified Action Right ID already contains the forumID + if (!forumIDs.Contains(forumActionRight.ForumID)) + { + // the list does not contain the forumID -> Add the forumID to the List of forum IDs. + forumIDs.Add(forumActionRight.ForumID); + } + } + + //Adds a new item to the session-state collection. + //If the name parameter refers to an existing session state item, the existing item is overwritten with the specified value. + HttpContext.Current.Session.Add("forumsActionRights", forumsActionRightsInSession); + } + + /// + /// Gets the forums action rights from the session. + /// + /// Dictionary of ActionRightID as a key and List of forumIDs as the corresponding value, if available otherwise returns null. + private static Dictionary> GetForumsActionRights() + { + if (HttpContext.Current.Session["forumsActionRights"] != null) + { + return (Dictionary>)HttpContext.Current.Session["forumsActionRights"]; + } + return null; + } + + /// + /// Checks if the user of the current context has the ability to perform the action right given + /// on the forum given. If this is correct, true is returned, otherwise false. + /// + /// Forum to check + /// Actionright to check on forum + /// True if the user of the current context is allowed to perform the action right on the + /// forum given, false otherwise. + public static bool CanPerformForumActionRight(int forumID, ActionRights actionRightID) + { + // Get the dictionary of ForumActionRights from the session. + Dictionary> forumActionRights = GetForumsActionRights(); + + if (forumActionRights != null) + { + // if there is an forumActionRights dictionary in the session + List forumIDs; + + // check if the dictionary contains a KeyValuePair with the specified ActionRightID key + if (forumActionRights.TryGetValue((int)actionRightID, out forumIDs)) + { + // Check if the List of forum IDs associated with the specified Action Right ID already contains the forumID + if (forumIDs.Contains(forumID)) + { + // the list contains the forumID + return true; + } + } + } + + return false; + } + + /// + /// Gets the forums to which the user has the specified action right. + /// + /// The action right ID. + /// List of forums IDs + public static List GetForumsWithActionRight(ActionRights actionRightID) + { + // Get the dictionary of ForumActionRights from the session. + Dictionary> forumActionRights = GetForumsActionRights(); + + if (forumActionRights != null) + { + // if there is an forumActionRights dictionary in the session + List forumIDs; + + // check if the dictionary contains a KeyValuePair with the specified ActionRightID key + if (forumActionRights.TryGetValue((int)actionRightID, out forumIDs)) + { + return forumIDs; + } + } + + return null; + } + #endregion + + #region Managing LastVisitDate + /// + /// Adds the lastVisitDate & isLastVisitDateValid to the session. + /// + /// The last visit date. + /// boolean to determine the validity of the last visit date + public static void AddLastVisitDate(DateTime lastVisitDate, bool isLastVisitDateValid) + { + //Adds a new item to the session-state collection. + //If the name parameter refers to an existing session state item, the existing item is overwritten with the specified value. + HttpContext.Current.Session.Add("lastVisitDate", lastVisitDate); + HttpContext.Current.Session.Add("isLastVisitDateValid", isLastVisitDateValid); + } + + /// + /// Gets the isLastVisitDateValid stored in the session object. + /// + /// The boolean value if available otherwise returns false as the default value. + public static bool IsLastVisitDateValid() + { + if (HttpContext.Current.Session["isLastVisitDateValid"] != null) + { + return (bool)HttpContext.Current.Session["isLastVisitDateValid"]; + } + + return false; + } + + /// + /// Gets the last visit date stored in the session object. + /// + /// DateTime of last visit date if available, otherwise returns DateTime.MinValue + public static DateTime GetLastVisitDate() + { + if (HttpContext.Current.Session["lastVisitDate"] != null) + { + return (DateTime)HttpContext.Current.Session["lastVisitDate"]; + } + + return DateTime.MinValue; + } + + #endregion + + #region Managing Search Terms and Results + /// + /// Adds the search terms and results to the session. + /// + /// A string of search terms. + /// A dataTable of search results. + public static void AddSearchTermsAndResults(string searchTerms, DataTable searchResults) + { + //Adds a new item to the session-state collection. + //If the name parameter refers to an existing session state item, the existing item is overwritten with the specified value. + HttpContext.Current.Session.Add("searchTerms", searchTerms); + HttpContext.Current.Session.Add("searchResults", searchResults); + } + + /// + /// Gets the search terms. + /// + /// string of search terms, and an empty string if no such value is present in the session + public static string GetSearchTerms() + { + if (HttpContext.Current.Session["searchTerms"] != null) + { + return (string)HttpContext.Current.Session["searchTerms"]; + } + + return string.Empty; + } + + /// + /// Gets the search results. + /// + /// A dataTable of search results, and null if no such value is present in the session + public static DataTable GetSearchResults() + { + if (HttpContext.Current.Session["searchResults"] != null) + { + return (DataTable)HttpContext.Current.Session["searchResults"]; + } + + return null; + } + + #endregion + + /// + /// Sets a temporary result in the session. The value is meant to be temporary. + /// + /// The key. + /// The value. + public static void SetTempResult(string key, T value) + { + HttpContext.Current.Session[key] = value; + } + + /// + /// Gets the temp result for the key specified from the session. It casts the value to the generic type T. + /// + /// The key. + /// the value stored in the session under the key specified, and cast to the type T. Is the default value for T key wasn't found + public static T GetTempResult(string key) + { + object value = HttpContext.Current.Session[key]; + if(value == null) + { + return default(T); + } + else + { + return (T)value; + } + } + } +} \ No newline at end of file diff --git a/GUI/App_Data/CollapseExpandScript.template b/GUI/App_Data/CollapseExpandScript.template new file mode 100644 index 0000000..597da45 --- /dev/null +++ b/GUI/App_Data/CollapseExpandScript.template @@ -0,0 +1,140 @@ +/****************************************************************************** + Expandable and Collapseable Menus v1.4 + + Grabs an elements id by using the toggle function and sets that element so it + is hidden. Once set hidden it creates a cookie that allows it to stay hidden + everytime that page is loaded. Hidden elements can be expanded by toggling + the menu back open. + + v1.1 - Open and closing of divs without cookies + v1.2 - Sets a cookie everytime the element is closed, but doesnt remember + v1.3 - Added a function to delete the cookie entirely + v1.4 - Function for saved elements which keeps them closed on page load + + Copyright 2006 Miles Johnson. www.mileswjohnson.com + + Adjusted for the forum system by Frans Bouma. +******************************************************************************/ + +// Lets begin shall we? Lets name our name state. +var stateObject = +{ + // Creates the actual cookie on the users browser + setCookie: function(name, value, expires) + { + document.cookie = name + '=' + escape(value) + '; path=/' + (typeof expires != 'undefined' ? '; expires=' + expires.toGMTString() : ''); + }, + + // Deletes the corresponding cookie + deleteCookie: function(name) { + document.cookie = name + '=' + '; expires=Thu, 01-Jan-70 00:00:01 GMT' + '; path=/'; + }, + + // Saves the id being closed in a cookie + saveCookie: function(id, state) { + var set = stateObject.getCookie('[RootCookieName]collapse_menu'); + var div = new Array(); + + if (set != null) { + set = set.split('\n'); + + for (var v in set) { + if (set[v] != id && set[v] != '') { + div[div.length] = set[v]; + } + } + } + + if (state) { + div[div.length] = id; + } + + expires = new Date(); + expires.setTime(expires.getTime() + (1000 * 86400 * 365)); + stateObject.setCookie('[RootCookieName]collapse_menu', div.join('\n'), expires); + }, + + // Gets a cookie to be used + getCookie: function(name) { + if (document.cookie.length > 0) { + start = document.cookie.indexOf(name + "=") + + if (start != -1) { + start = start + name.length + 1 + end = document.cookie.indexOf(";",start) + + if (end == -1) + end = document.cookie.length + return unescape(document.cookie.substring(start,end)) + } + } + return null + }, + + // Opens or closes the divs + toggle: function(id) { + var div = document.getElementById(id); + var collapseImageDiv = document.getElementById("Collapse" + id); + var expandImageDiv = document.getElementById("Expand" + id); + + collapseImageDiv.style.display = 'none'; + expandImageDiv.style.display = 'none'; + + if(div.style.display == 'none') { + stateObject.saveCookie(id, false); + div.style.display = 'block'; + collapseImageDiv.style.display = 'block'; + expandImageDiv.style.display = 'none'; + } else{ + stateObject.saveCookie(id, true); + div.style.display = 'none'; + collapseImageDiv.style.display = 'none'; + expandImageDiv.style.display = 'block'; + } + }, + + // Loads the divs to their state + loadDivs: function() { + var set = stateObject.getCookie('[RootCookieName]collapse_menu'); + + if (set != null) + { + set = set.split('\n'); + + for (var v in set) + { + var div = document.getElementById(set[v]); + var collapseImageDiv = document.getElementById("Collapse" + set[v]); + var expandImageDiv = document.getElementById("Expand" + set[v]); + + // set initial values. + collapseImageDiv.style.display = 'block'; + expandImageDiv.style.display = 'none'; + + if (div == null) + { + stateObject.deleteCookie('[RootCookieName]collapse_menu'); + } + else + { + div.style.display = 'none'; + collapseImageDiv.style.display = 'none'; + expandImageDiv.style.display = 'block'; + } + } + } + else + { + stateObject.deleteCookie('[RootCookieName]collapse_menu'); + } + } + +} + +//========================================== +// Initialize +//========================================== + +window.onload = function() { + stateObject.loadDivs(); +} diff --git a/GUI/App_Data/Noise.txt b/GUI/App_Data/Noise.txt new file mode 100644 index 0000000..803a933 --- /dev/null +++ b/GUI/App_Data/Noise.txt @@ -0,0 +1,124 @@ +about +1 +after +2 +all +also +3 +an +4 +and +5 +another +6 +any +7 +are +8 +as +9 +at +0 +be +$ +because +been +before +being +between +both +but +by +came +can +come +could +did +do +each +for +from +get +got +has +had +he +have +her +here +him +himself +his +how +if +in +into +is +it +like +make +many +me +might +more +most +much +must +my +never +now +of +on +only +or +other +our +out +over +said +same +see +should +since +some +still +such +take +than +that +the +their +them +then +there +these +they +this +those +through +to +too +under +up +very +was +way +we +well +were +what +where +which +while +who +with +would +you +your +code +quote +i +b +s +otis +Frans diff --git a/GUI/App_Data/RegistrationReplyMail.template b/GUI/App_Data/RegistrationReplyMail.template new file mode 100644 index 0000000..c92e046 --- /dev/null +++ b/GUI/App_Data/RegistrationReplyMail.template @@ -0,0 +1,17 @@ +Dear user, + +You've succesfully registered yourself to the forumsystem [SiteName] +at: [URL] ! + +To get access to the forums, you have to login using the nickname you provided +and the password specified below. + + Your password: [Password] + +Have a nice forum-life at [SiteName] ! + +Best regards, + + Crew of [SiteName] + [URL] + diff --git a/GUI/App_Data/ThreadUpdatedNotification.template b/GUI/App_Data/ThreadUpdatedNotification.template new file mode 100644 index 0000000..b902664 --- /dev/null +++ b/GUI/App_Data/ThreadUpdatedNotification.template @@ -0,0 +1,12 @@ +Dear user, + +The following [SiteName] thread to which you are subscribed has been updated: + +Subject: [ThreadSubject] +Thread URL: [ThreadURL] + + +Best regards, + + Crew of [SiteName] + [SiteURL] \ No newline at end of file diff --git a/GUI/App_Data/ubb_message.xsl b/GUI/App_Data/ubb_message.xsl new file mode 100644 index 0000000..914a716 --- /dev/null +++ b/GUI/App_Data/ubb_message.xsl @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Code:
+
+ + + + + + + + + +
wrote:
+ +
+
+ + + + + + + + + +
Quote:
+ +
+
+ + + + + + + + + + + {@alt}
+
+ + +
+
+ + + + + + +
    + +
+
+ + +
    + +
+
+ + +
    + +
+
+ + +
  • + +
  • +
    + + + + + + +

    Offtopic:

    +
    + + + + + + + + + + + + + + + Regular Smiley + + + + Angry + + + + Laugh + + + + Wink + + + + Cool + + + + Tongue + + + + Confused + + + + Shocked + + + + Dissapointed + + + + Sad + + + + Embarrassed + + + +
    +
    + + + + + + + + +
    \ No newline at end of file diff --git a/GUI/App_Data/ubb_signature.xsl b/GUI/App_Data/ubb_signature.xsl new file mode 100644 index 0000000..f9f0aed --- /dev/null +++ b/GUI/App_Data/ubb_signature.xsl @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
    +
    + + + + + + + + + + + + + + :) + + :( + + :D + + ;) + + 8) + + :P + + :? + + :o + + :/ + + ;( + + :! + + +
    +
    + + + + + + + + + +
    + \ No newline at end of file diff --git a/GUI/App_Themes/BlueAndGrey/main.css b/GUI/App_Themes/BlueAndGrey/main.css new file mode 100644 index 0000000..9e3270e --- /dev/null +++ b/GUI/App_Themes/BlueAndGrey/main.css @@ -0,0 +1,558 @@ +/**********************************************/ +/* */ +/* HTML Tag styles */ +/* */ +/**********************************************/ + +A +{ + color : #5674B9; + text-decoration : underline; +} + +A:visited +{ + color : #5674B9; +} + +A:active +{ + color : #5674B9; + background : #9A9A9A; +} + +A:hover +{ + color : #EFEFEF; + background : #5674B9; + text-decoration : none; +} + +BODY +{ + font-size: 9pt; + color: #000000; + font-family: verdana, arial, helvetica, sans-serif; + background-color: #F4F4F4; + background-image: url("pics/background_page.jpg"); + background-position: left top; + background-repeat: repeat-x; + background-attachment: fixed; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; +} + +CODE, PRE +{ + font-family: Verdana , 'Lucida Console' , 'Courier New' , sans-serif; +} + +HR +{ + border-top: #5674B9 1px solid; +} + +IMG +{ + border-style:solid; + border-color:#9A9A9A; +} + +SELECT +{ + font-size: 9pt; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + +TD +{ + font-size: 9pt; + color: #000000; + font-family: verdana, arial, helvetica, sans-serif; +} + +TEXTAREA +{ + border-right: #5674B9 1px solid; + border-top: #5674B9 1px solid; + font: 9pt Verdana, Arial, Helvetica, sans-serif; + border-left: #5674B9 1px solid; + color: #000000; + border-bottom: #5674B9 1px solid; +} + +/***************************************************************************************/ + +/************************************************/ +/* */ +/* CSS Classes, used in the pages */ +/* */ +/************************************************/ + +/************************/ +/* Tag specific classes */ +/************************/ + +/* Class for links which shouldn't have any decoration. */ +A.LinkNoUnderline +{ + text-decoration: none; +} + +/* Class which is used with Thread subjects which are a link. */ +A.ThreadSubjectLink +{ + font-weight:bold; +} + +/**********************/ +/* Base color classes */ +/**********************/ + +/* Class to be used in tabular lists to get a slighter lighter background in the row. */ +.LightBackground +{ + background-color: #EBEBEB; +} + +/* Class to be used in tabular lists to get a slighter darker background in the row. */ +.DarkBackground +{ + background-color: #DADADA; +} + +/* Class to be used in tabular lists to get the normal background color as set in the body in the row. */ +.NormalBackground +{ + background-color: #E5E5E5; +} + + +/**************************************************/ +/* Tabular data and form oriented classes classes */ +/**************************************************/ + +/* Class for an empty row in a tabular list of data to keep the lines in the table */ +.EmptyRow +{ + border-top: #5674B9 1px solid; + border-bottom: #5674B9 1px solid; +} + +/* Class for an empty row in a tabular list of data to keep the lines in the table, however this class has only the top border defined */ +.EmptyRowOnlyTopBorder +{ + border-top: #5674B9 1px solid; +} + +/* As EmptyRow, but now at the bottom of a tabular list of data */ +.EmptyRowBottom +{ + border-top: #5674B9 1px solid; +} + +/* Class used for a table definition which are used as the explanation boxes on pages. */ +.ExplanationBox +{ + border: solid 1px; + border-top-color: #AAB9DC; + border-left-color: #AAB9DC; + border-right-color: #AAB9DC; + border-bottom-color: #AAB9DC; + background-color: #DADADA; + background-image: url("pics/background_explanationbox.gif"); + background-position: left top; + background-repeat: repeat-x; +} + +/* CLass for the normal form buttons, used everywhere in the application. */ +.FormButtons +{ + font-size: 9pt; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + + +/* Class for flat form buttons used in the message editor, for example the [b] [i] etc. buttons */ +.FormButtonsFlat_Light +{ + font-size: 9pt; + color: #333333; + background-color: #fcfcfc; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + +/* Class which is used a fill in form window, which is placed inside FormContent */ +.FormWindow +{ + background-color: #DADADA; + background-image: url("pics/background_explanationbox.gif"); + background-position: left top; + background-repeat: repeat-x; +} + +/* Class which is used for a general small border table with borders around every cell. This class is used + * in the IP Ban list and in the MessageEditor control where it's used above the smiley list for the caption. */ +.GeneralSmallBorderTable +{ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #333333; + background-color: #DADADA; + border: #5674B9; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; +} + +/* Class used for a table definition which are used as the legend boxes on pages. */ +.LegendBox +{ + border: solid 1px; + border-top-color: #AAB9DC; + border-left-color: #AAB9DC; + border-right-color: #AAB9DC; + border-bottom-color: #AAB9DC; + background-color: #DADADA; +} + +/* Class used for the message header, which is the header right above the message text containing post date and ip number. */ +.MessageHeader +{ + font-size:8pt; + border-bottom: #D5DCED 1px solid; + color: #787878; +} + +/* Class used for the message footer, which is the footer right below the message text containing signature of the poster and the 'top' link. */ +.MessageFooter +{ + font-size:7pt; + border-top: #D5DCED 1px solid; + color: #787878; +} + +/* Class for the slightly bigger text in the description text of the author of the message next to a message */ +.SmallFontAuthorSmaller +{ + font-size:7pt; + color: #000000; +} + +/* Class for the smallest text in the description text of the author of the message next to a message */ +.SmallFontAuthorSmallest +{ + font-size:6pt; + color: #000000; +} + +/* Class for slightly bigger fonts than SmallFontSmallest */ +.SmallFontSmaller +{ + font-size:8pt; +} + +/* Class for very small fonts, used everywhere in the application */ +.SmallFontSmallest +{ + font-size:7pt; +} + +/* Class for the small font used in threadlists */ +.SmallFontThreadList +{ + font-size:7pt; + color: #777777; +} + +/* Class for the area in which support information is placed above messages in message view */ +.SupportArea +{ + background-color: #F5F5F5; + border-bottom: solid 1px #D5DCED; + border-top: solid 1px #D5DCED; + border-left: solid 1px #D5DCED; + border-right: solid 1px #D5DCED; +} + +/* Class which is used for the headers in the support area sections: Support Queue management and Memos */ +.SupportAreaHeader +{ + color: #000000; + background-color: #D5DCED; + background-image: url("pics/background_supportarea_1line.gif"); + background-position:top center; + background-repeat: repeat-x; + + font-weight: bold; + font-size: 8pt; +} + +/* Class for a row in the support area in which support information is placed above messages in message view */ +.SupportAreaRow +{ + border-bottom: solid 0px #D5DCED; + border-top: solid 0px #D5DCED; + border-left: solid 0px #D5DCED; + border-right: solid 1px #D5DCED; +} + +/* Class which is used for the container in which a form or table content is placed. */ +.TableContent, .FormContent +{ + background-color: #5674B9; +} + +/* Class which is used for the column headers in tabular data in tables. */ +.TableColumnHeader, .FormColumnHeader +{ + font-weight: bold; + font-size: 8pt; + border-right: #D5DCED 1px solid; + background-color: #D5DCED; + color: #000000; +} + +/* Class which is used for the description displayed below a TableName or FormName. Only used in TwoLine table / form headers. */ +.TableDescription, .FormDescription +{ + font-size: 7pt; + font-weight: normal; + margin-left: 10px; + padding-top: 0px; +} + +/* Class which is used for the table header for tabular data with a 2-line header or a form header with two lines, used everywhere in the application. */ +.TableHeaderTwoLine, .FormHeaderTwoLine +{ + color: #EFEFEF; + background-color: #5674B9; + background-image: url("pics/background_tablehd_2line.jpg"); + background-position:top left; + background-repeat: repeat-x; +} + +/* Class which is used for the table header for tabular data with a 1-line header or a form header with one line, used everywhere in the application. + * One line headers don't have a description. */ +.TableHeaderOneLine, .FormHeaderOneLine +{ + color: #EFEFEF; + background-color: #5674B9; + background-image: url("pics/background_tablehd_1line.jpg"); + background-position:top left; + background-repeat: repeat-x; +} + +/* Class which is used for the name displayed in a table header of form header */ +.TableName, .FormName +{ + font-weight: bold; + font-size: 11pt; + margin-left: 4px; + padding-bottom: 0px; +} + +/* Class which is used for a row in tabular data. */ +.TableRow +{ + font-size:9pt; + border-right: #D5DCED 1px solid; + color: #000000; +} + +/* Class which is used for a row in tabular data which is selected, like in a gridview. */ +.TableRowSelected +{ + font-size:9pt; + border-right: #5674B9 1px solid; + background-color: #D5DCED; + color: #000000; +} + +/* Class which is used for the sub name of a table or form. This subname is displayed below the name in a slighter smaller font. Example usage: thread subject + * in messages view (Messages.aspx) */ +.TableSubName, .FormSubName +{ + font-size: 10pt; + font-weight: normal; + margin-left: 10px; + padding-top: 0px; +} + + +/* Class used for a TD definition which is used as the welcome box on the startpage */ +.WelcomeBox +{ + font-size:8pt; +} + + +/****************************/ +/* Header related classes */ +/****************************/ + +.HeaderTop +{ + background-image: url("pics/background_header_top.jpg"); + background-position: top left; + background-repeat: repeat-x; + background-color: #5674B9; + color: #EFEFEF; +} + +.HeaderBottom +{ + background-image: url("pics/background_header_bottom.jpg"); + background-color: #5674B9; + color: #EFEFEF; +} + +.HeaderLinkTop +{ + color : #EFEFEF; + background: Transparent; + text-decoration : none; + font-weight:bold; +} + +.HeaderLinkTop:visited +{ + color : #EFEFEF; + background: Transparent; +} + +.HeaderLinkTop:active +{ + color : #EFEFEF; + background: Transparent; +} + +.HeaderLinkTop:hover +{ + color : #EFEFEF; + background: Transparent; + text-decoration : underline; +} + +.HeaderLinkBottom +{ + color : #EFEFEF; + background: Transparent; + text-decoration : none; +} + +.HeaderLinkBottom:visited +{ + color : #EFEFEF; + background: Transparent; +} + +.HeaderLinkBottom:active +{ + color : #EFEFEF; + background: Transparent; +} + +.HeaderLinkBottom:hover +{ + color : #EFEFEF; + background: Transparent; + text-decoration : underline; +} + +.HeaderSeparator +{ + color: #5674B9; +} + + + +/***************************************************************************************/ + +/*******************************************************/ +/* */ +/* CSS Classes, used in messages HTML */ +/* */ +/*******************************************************/ + +/* Class for text defined with the [size] UBB tag and size value 1 */ +.MessageFontSize_1 +{ + font-size:6pt; +} + +/* Class for text defined with the [size] UBB tag and size value 2 */ +.MessageFontSize_2 +{ + font-size:7pt; +} + +/* Class for text defined with the [size] UBB tag and size value 3 */ +.MessageFontSize_3 +{ + font-size:9pt; +} + +/* Class for text defined with the [size] UBB tag and size value 4 */ +.MessageFontSize_4 +{ + font-size:12pt; +} + +/* Class for text defined with the [size] UBB tag and size value 5 */ +.MessageFontSize_5 +{ + font-size:14pt; +} + +/* Class for text defined with the [size] UBB tag and size value 6 */ +.MessageFontSize_6 +{ + font-size:18pt; +} + + +/* Class for text defined with the [code] UBB tag. Text surrounded by [code] UBB tags is placed inside a table. + This class is used on the TD of the table which contains the actual text */ +.CodeText +{ + border-right: #D5DCED 1px solid; + border-top: #D5DCED 1px solid; + font-size: 7pt; + border-left: #D5DCED 1px solid; + color: #444444; + border-bottom: #D5DCED 1px solid; + background-color: #fcfcfc; +} + +/* Class for text defined with the [quote] UBB tag. Text surrounded by [quote] UBB tags is placed inside a table. + This class is used on the TD of the table which contains the actual text */ +.QuoteText +{ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #333333; + background-color: #fcfcfc; + border: #D5DCED; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; +} + +/* Class for text defined with the [offtopic] UBB tag. Text surrounded by [offtopic] UBB tags is placed inside a span which uses this class. */ +.OfftopicText +{ + font-size: 7pt; + color: #777777; +} + +/***************************************************************************************/ diff --git a/GUI/App_Themes/BlueAndGrey/main.skin b/GUI/App_Themes/BlueAndGrey/main.skin new file mode 100644 index 0000000..b43bb01 --- /dev/null +++ b/GUI/App_Themes/BlueAndGrey/main.skin @@ -0,0 +1,113 @@ +<%-- + + Main skin for the HnD theme. + + --%> + +<%-- The logo image as shown in the header of every page --%> + + +<%-- The link URL of the anchor in which the logo image is placed on every page --%> + + +<%-- The imagebutton used to mark a thread done and which is shown when a thread isn't done in message view --%> + + +<%-- The image shown when a thread is marked done in message view --%> + + +<%-- The imagebutton used to subscribe to notifications for the current thread in message view--%> + + +<%-- The imagebutton used to unsubscribe from notifications for the current thread in message view--%> + + +<%-- The imagebutton used to bookmark the current thread in message view--%> + + +<%-- The imagebutton used to unbookmark the current thread in message view--%> + + +<%-- The image used for the print button in message view to print the whole thread --%> + + +<%-- The image used for the move thread button in message view to move a thread --%> + + +<%-- The image used for the delete thread button in message view to delete a thread --%> + + +<%-- The image used for the close thread button in message view to close a thread --%> + + +<%-- The image used for the thread properties button in message view to view the properties of a thread --%> + + +<%-- The RSS button used in forum/thread views --%> + + +<%-- Image used in thread view to show that a sticky thread has new posts --%> + + +<%-- Image used in thread view to show that a sticky thread has no new posts --%> + + +<%-- Image used in thread view to show that a normal thread has new posts --%> + + +<%-- Image used in thread view to show that a normal thread has no new posts --%> + + +<%-- Image used in thread view to show that a closed thread has new posts --%> + + +<%-- Image used in thread view to show that a closed thread has no new posts --%> + + +<%-- Image used in thread view to show that a sticky thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a sticky thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a normal thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a normal thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a closed thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a closed thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread lists to show that a thread is marked done --%> + + +<%-- Image used in thread lists to show that a thread isn't yet marked done --%> + + +<%-- Legend variant of imgIconNoNewPosts --%> + + +<%-- Legend variant of imgIconNewPosts --%> + + +<%-- Legend variant of imgIconNoNewPostsClosed --%> + + +<%-- Legend variant of imgIconNewPostsClosed --%> + + +<%-- Legend variant of imgIconNoNewPostsSticky --%> + + +<%-- Legend variant of imgIconNewPostsSticky --%> + + +<%-- Image used for the Expand section button of the front page --%> + + +<%-- Image used for the Collapse section button of the front page --%> + diff --git a/GUI/App_Themes/BlueAndGrey/pics/HnDLogo.jpg b/GUI/App_Themes/BlueAndGrey/pics/HnDLogo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..efd836b1181e4af7c26167980296ca2a81310101 GIT binary patch literal 22150 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 H?0^5+zKm=K literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/background_explanationbox.gif b/GUI/App_Themes/BlueAndGrey/pics/background_explanationbox.gif new file mode 100644 index 0000000000000000000000000000000000000000..f019a8a1e001dffccd5a86a8d6a9d254b91db050 GIT binary patch literal 14146 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 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/background_header_bottom.jpg b/GUI/App_Themes/BlueAndGrey/pics/background_header_bottom.jpg new file mode 100644 index 0000000000000000000000000000000000000000..981946d66c621dcaef2bacd5726287b53ad0282d GIT binary patch literal 1841 zcmbu7X;4#F6vuB!FlcQ71uT{hB2ep^O4I@ZDWV`QAll+Wfx049sE7ec2(Mx_E)`tC z1$d(wM)8XgJ=1OoWMdH^m0A!FGG#hAzk35aCPBzOQDM*`82fVTj500_2k zwZXd}*bqs!pLJh+D`JAA3Sby)MoPZ6ephp zr!L!hF1gj@y!Nrii@IfR_V@`dQ$BT_>ixxxFK5nLuyE1WzJC58OP7U)Ee~I@?%VI8 z*KgRkY3sJ_I}&y#{+POto|e8pgK_YeLxys9 zg8hrj(aL2*A`waCF)o5ly7dwrNwyyI$4v^3B5zKaJl*Gjozs$2mv1$V_oS}XIB(he zc!G=9f*x<}7~0=t{|zkrf04Zh`-iIwOe7Ml!y`HZ8nBRXaHvPS9y`WvnP=xd=s$d> z0P0>vS1}l`x6T-)*dOETzYX$mHy37x`s1K`)jqjmu?aOMn65Ru>m#%@U5q+5Sj;?upEBxyV1iR;J3Z7rYaP zdJ-j(*hc$Oog~+=@-Wm_&>DR_vzWq=<6zB@y1&Dm{irGo2UNE#6bG3tiBDZ;4 z&|S@Nxmdz(@xVbU=V)M9Nh#7JS^(Wu50?uu7k0}W1`h5fNmdzfaI=Vo6;hY<%=>f` zRDNNy;?e^j9L&W*r(PFVPd469fJR)mnjzkn0KQySq`tul!KSe9t;4~>5Qzg~iQsvC zPHl&{!$>JvW9?vVjDuw%k|~%A&ua(=WhZGR!vL@E1TylIxZ17E|{&a`@a&IumB2aRxRy? zk!e>}|9xZ8CX=y7oLd4@&AZc}%!BO=y2&v|{2*8PP$rXJCYczz?py&};mt;S!uu)) zqZ=FI)eOCTqMT_;6UNnJE1E1di~VF`u|~1KwIA`iNUI$eOi}qs157Cc`e730N$#vmo7+7JTO(nJOoi`9w)`_yH$a-Nu3HB!#zT2q5A z05b0x$~rF#a7#ES^phHp3XcxN6MDl6WuEpWmnqTgR3$4mjbX7^mle)xD+m(CH=rvs z+z*Re?cSASk+Arbh(N|fsfgqq{PixDn9>kY+h3`YRmaRuHw-hm9C4+YPU9kJ zo}RU9pb%tt(VlPGgNx0pt4?EBr@-@b4MB?51*|Ene8EAP87%RF~1j?imn1Lda7#Q#T3%AON_W%F@ literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/background_header_top.jpg b/GUI/App_Themes/BlueAndGrey/pics/background_header_top.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce6e8e699535f8d6c4c87b62fd12e4ca67a3a6d4 GIT binary patch literal 5733 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 AAOHXW literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/background_page.jpg b/GUI/App_Themes/BlueAndGrey/pics/background_page.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2bc4701f2d7abb06574a9ba07832718805186a8 GIT binary patch literal 13695 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 ZZ6+=~nZo*tU(RuI!91~qK92-M{{UR3BG&)_ literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/background_tablehd_1line.jpg b/GUI/App_Themes/BlueAndGrey/pics/background_tablehd_1line.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e34866d2236e6adddb066bf5becf797456add9bb GIT binary patch literal 774 zcmex=8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA36hG?q9n;@Bd@G?N`nHxEKE_ zL&L-CXGOidy=~v}9^R7ApXXVpzr0g;`OhbV`L~xh?&x3n_UGd-Hf3k4_lHMSTK`$I z=G)tsue0T{R{ni!TUu@RJ$Bz;t2tVm6YG*sT0Z&wedWU0i9csIA6LJ%mwEDaz9S86m5{#k)@uku(g0DmS2M&cw3=mTXma3#cl~tEy7AGJD3}AqSBwAMK z94A5C`YiIr4bN~3A z`@7$BKKJ6^;V;3;cjFV{0f9gOe_U7q*MohF-7l)ekY5zAcp1MB0+)hqAf8Cr2z&ww z#6SZ67=!>o@cl6x{8R)VBFT3NdFe90H)&;%(#@642ZrlE5MC4n$qo{lK z{Vpzk|2qlqro4anNb2uDIGT3iPbbqeGEe0foZ%G~74u8~{K@&UPyceEvg&V_E?>EN z?fR{{&+8jxx4-!N-LG0&+Z6w}*Z%O)W!eF1UP1BqE8t=py(OE^J~T$#-M;l2wc(@^S9!O*_vm zUGw&5wRavY+q^5;y7t4oUccA2L=11WEzW{(>>YwwK2+Kx=mPMdnqPw?k~ zUCS2=X~Lbt+hT!2jsuRHBKiCRb={!+2i05~!h3Yh(0s#eY!~f7#zIcvAVXB*bfFTy zcu%Z0M$CR>&^o%XqPi-k^42SLmM6DyXt?_Ys;+LAe{E6CxtOg2hYJ&)7IXTppnLs0 znTaDfXo5=8B#wJ@+N4r1Z1F1m3&njNi_&0YifI?Z%H(5=xnfjr8;MAIYSPqMlo5V8 zgQA)FL>v@%3DrSvyM#X;L`9#326wh|_v>dzJFP`91F}9zyk_)6o%{lxo~>Z@d)xH= zQVfoh9YS-eTTJ>x{7-Z52YpXZynkkV!}#qHwTR)g(kq&Gb(u;{o*9!NqCXOOE}zZS zJXe~=!cMm7L~pg3RW&N!I&`FYDk`d*tfB?pCmYTURC)IT(MQHoGtALM+iSQr4neHb zWY%CRUg~ljup$$Vv7dJ$W82iEm%Bq%`_mAJJ+hvbQ1l8znDPOZ*jmIoFZuS zR&Q=jW1QxnVctQP7s?hDVppLYn0BW|M>IW+=IYC5USIEb3aVCS;(&}joUT(;_EL5@ z&yH6i5^i}#epkprV?oSzaSMnJpAfjlwRV#`of4OHk6zMieZ1 zW0NIhAlUs4bI1rK7hz}3hNi_V$kYYzE%KyOv4qX_M!EfHX10pO&*Tb@47v1KSzjsj zz4{Z?u9cHSM5fvWr63Z+K4en`8cd~b2xf#v3tY|_W8s=N`5&pKoYSNA9bdKtWO(O~ zvIj+3*%3WV6wn~}qA;Ewj>PN?@D;a^^R+k-U==BFX!)xQC;LF7K2C9k6FI6CA5uu2ZgICDq_2~F$i+ltGg&xzXKajpUC*M4Az1U?ZXBQ@V#Q5kO`Q}%?g~3b zrbX)cW@)-A;9&WCUv$!kEiE`G74J>fopGxMEDH7!O~H0`%nciy)B`03xZ(HbdmOnr z>OWLoP3Gj%%mv78~!Wp$o^b|la3Z0%R#pi=nB8|V3V)`!EnChUnl)&LJ-9*?M+ zA0R)SM>lym4SF0LNP0G4%I;TjE=|`@k7lQ!o5Jf#ePaiubhc3CMZ{eT}fv%em z@id1|TAEr_g`BfO`FgJ;3a+IHnHp(N7#x%~yBa>|wN>Wr7pFWonngEQ;=+aj)2x&6 zt(}Df>#rS1s*XGWHw#M(EcsHS)UFA&-ejc*h03C(FITMKI-Kz7xUIixY8X^Dat@ef zBRRF*7^=^X85FUc~!7LM!w1%BD7 A)c^nh literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_bookmark.gif b/GUI/App_Themes/BlueAndGrey/pics/button_bookmark.gif new file mode 100644 index 0000000000000000000000000000000000000000..7338885f5751b501c01204f329ac78ece42f78b8 GIT binary patch literal 1251 zcmV<91RVQENk%w1VH*G%0QUd@8zea#COm#=J0B`TAS^~CF-|2iP$xB2D>_{)JYOw(1eQj)c zYi@m|eh{O5AEbO7h-@;CbvvAVJb-LUj(J0XbX|*lWU`13wu%p^fElWT9jApZzLP4a zggV5Q1Kh6w*Qf~EsSe7a72mWH>$?Hqw-UgaBEg$C%A+L6r7hU8Bf_LJ#-=&ewln(5 z0RPSb|IP*U$qE0@3jfjq|I-Eg(Fp(05C7B-|JV!d!V>?}5&zT||JfJ+)ENKPAOF}R z{@Nt}-Y5UpDErtb|Jy15+AaUwEbPfK|J^eG-!=c|Km3Q<2wK3Jeh!5u8U2+ znnkdYSG<{3kAY~Igl3F_cB71Eua#}FmS?em=t=+VNdN9m{pM2t<5d6cQvdB#|KnW$?OXrrT>tQ0 z|MXny)MEPHZT{k7|LAQ|MPVJ_ICgJdp=Z#LtBtrXN*T+nptg~U~G+K zZ;fVfjBIm{Zgq}wbb)tyfq8j{V{VXOZk1(nlx=pDZg`e%d!BZFm2!NUaD1IiW}{7K zrCM*JSZ<|JZLVE%rB`sPT5_vgbE{KtvR8AnRdTjibFo`>vtDoDZ!a#q z`We(F(M{9*&;W6YDNUz8zo26RB!w!gLUGX|h3QkMUB6_d>GlH&3QoFu?E-ZP)2yZ^ zlZ|=SEDoGEV#ERZ!9<4$HFB0Y3+KiJUR-Qg(9x#Oo;hymoB(;kryRX=*81$}G2-zo zO)HWR^491N6(B~mAo}J_(H0*r1h9IXQdI~UQ}kq60>lX(M&2CVnekx)s#?5Lw&LKS zMinJOun4;5t&WWckyJ*=SGfU9H6=~#Eb@jehl5ozuMS%gjl8IOEg>zfddA$Sb_#Q zUIalxEaJ&`Q!T-?kw_6Ie3()tXN=Rx4jRN5VM@S+5km(Q#N+* NpMVY!0003206YA8eNX@Z literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_close.gif b/GUI/App_Themes/BlueAndGrey/pics/button_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..dc215ff3f49c2c6cbe492f49786c6436c49bb556 GIT binary patch literal 1206 zcmdthc{|$&0KoAdD`V^7nb!7TE2TA>>3AM}T&*L{h&1jtG>MF0N-MM-I+X}{9>=84 zmZ%((R_cf&j$ou|QX*9(N|mQ%@vN@W)Da@Fr*C85ckub+>mTUn>=J7Rm;$>1U}o)N ze$E{k@iQt4loaV2i*&hxxQs!&VbJcU?Z6fwKWhirSx2~yQ^a}K>mYZOQ{Zoo;AH2Z zKU}ZmxWVsx!;q;l-f1W>4(*>2>wgy;oSAUtUUDe@Run!BLBK^5(-A~mbp9O_=`O0| zUP5tB5;xy|yvA|zv9pxwDx+PhCHX$B2rth|sV8Sq$=UR>KmTT9hM9qHSm2o^=)3mt z`RV5=9!%cQNK-Vjo6Dm)+G*V3bo${;hW2gdu2IJSt#5BsJBN*p&Px3W-B6>Y$f&(EsXUk-MKf;5AnE zKdbI;q6~8Co_8{YeJzS%;+TLtF)|>R(ATFKib=M7sz!i?hAitCc(Iz5RndwMMJe0{@plUm#yz01OU+OSi?uMk+tgz!-@U z_)3|9DQ6&*fHu161!EA`%ZkN#S!w|$w8^QHHNT=m*)b#S@!#7WgVGf~9jsSX=TRbe z!vfTU7oFJrABabA(Nx*qWW( zpcvw%plhvwlNeYrCc41w6OlD#<)Fy>st^2h66{CkRCK>Zc}5!qX0#7-jE8(@?N?}i z%0ouq#a3lQeUs=f42;f%Qb3J-zDsgtCd8pOFw{qs`@?MM`1nHIzhbus5->R!b*E>*>xGXek|9l-5BIy)72 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_collapse.gif b/GUI/App_Themes/BlueAndGrey/pics/button_collapse.gif new file mode 100644 index 0000000000000000000000000000000000000000..21e645af4ab70fb0e3ccfe396f0f59c10062e005 GIT binary patch literal 388 zcmV-~0ek*ONk%w1VH5xq0M!5h940*-Cq5r4Lm@3kBr#4aI$bS2VJ<#nFhFKBMsGJu zcR5XaJW+x^RE0iNhC^DALtBwXUzkW?n@nepcDh@5yIp#` zVST(|eZ6IWy=H;HYlXsci^X(}#d?v*dXmV1mBoOT%7K^5g`3QVo6VW1%#Wkdl&904 zuh*!x(W$l3qqEtjwc4n-+p4+TzsK3d%i7=I$11ao)NBoDQ*F&KA~wY0r@@= z`GJwSEC=KT=LBZX_eopqo4(XPW07yhQvb}Qfmw@#vX_PA zED6Y28I-dkC}(A8{_4QowL!US0&~{|=B*FPTNjkKJ|rJVZV1lb6kM<|xL{LA;pULS zEg?l)LyNYC6>SME+7?>8J*;?JSn>AI;vHc?R02dhW2^SWSMN=2+@IcbAgkqIQTNf3 z-lJvx$EqivXqj-K<0q* z0t3f?24%;hD=QWpY~~O)GMe&CP}!wj$!m_sMx}-3W@55JEGrft?^kgCm09EzxX`{X zXjRO~O-pAftNJX;@tpkZ^bGavS22~r&%6xnHhsCda#Q-bDK+yRoM=pa;boh)=tIj( zr`uQ z5XpXYr14^cPr_-P*DE9x7J8qu%yHXu!1;Qiml`9_nTo|l=clv8{SZ02c9I_tgY3FD zk)6-mgj+{`vZDUZKW<#v{Be hVi^w_Ij%JvVhuWRfRRnWP2*vUNL&B|BO@b&H2@&CG-&_; literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_done.gif b/GUI/App_Themes/BlueAndGrey/pics/button_done.gif new file mode 100644 index 0000000000000000000000000000000000000000..799631920c62b585d67329c677f82b2e7185923b GIT binary patch literal 999 zcmZ?wbhEHblxC1(_|Cwf{Z`!Ip0?R}d*kb-de0OMUnyEV({b3C;k>fQZBdQI2~X<- z!M=BV+#WbaUrkK9loMRDKCEP?=d3or?%CdxCImJwtvxzz(ynbYw;yB}1*0J_q(T6g zk`;flFfuUwXV3vT9F!**IF2y<=ali-u;5@bhp<-6i46}AaWZR39C6sV=xDcyJVOFQ zqSCQ`2|W{r4-AJLyLi-D7$z_*J>Jg3;ql}7ri8Q2!W;|>6h1t2n9owY=}+b-Rlm6$ z9860iw&4IE8zm<)jjs6~=u6uL4%m2Ux>ClA_y4Y?+F=PtryRx&I V6|dVN;N;%EB6xM&UMmF#YXFnbdcyz! literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_done_small.gif b/GUI/App_Themes/BlueAndGrey/pics/button_done_small.gif new file mode 100644 index 0000000000000000000000000000000000000000..a3e065c55c99601e885bca55103c8cb0d95f45c9 GIT binary patch literal 873 zcmZ?wbhEHbGFex5pALr+gG)QFvELm_Lj?wF02(GK*#H0l literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_expand.gif b/GUI/App_Themes/BlueAndGrey/pics/button_expand.gif new file mode 100644 index 0000000000000000000000000000000000000000..f39c8876e3d9b881d96c4182bce5f1980be46a1a GIT binary patch literal 389 zcmV;00eb#NNk%w1VH5xq0M!5h940*-Cq5r4Lm@3kBr#4aI$bS2VJ<#nFhFKBMsGJu zcR5XaJW+x^RE0iNhC^DALtBwXUzkW?n@nepcDh@5yIp#` zVST(|eZ6IWy=H;HYlXsci^X(}#d?v*dXmV1mBoOT%7K^5g`3QVo6VW1%#Wkdl&904 zuh*!x(W$l3qqEtjwc4n-+p4+TzsK3d%i7=I7hHG(0pIh>C%Xbr_G49Fvuoux}Wgo}e6RxoN4ZX{BkuaK?7Pbh^un2q7I7 j6xG((*Aoo}7ZD5#;Njxp3I_xZ1p@->?CtIV0YLyev-hu# literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_move.gif b/GUI/App_Themes/BlueAndGrey/pics/button_move.gif new file mode 100644 index 0000000000000000000000000000000000000000..066c2a842097ae6bd247a32b19065b9d0d152ad4 GIT binary patch literal 699 zcmZ?wbhEHblxC1(c*ejWtzs#oW|J4MU!HCxujQ6{}+tZ|a$B z%1It;r+IFj>$_)hz`mscm$ygW+8gusY|8(; zx&QAK{(n&Z|3TIN2i5-{*4Tx#*@w0}M^A81nB|kU*f)J?VD8$$+;xF@>x1(*g%)iK zE#4khvLmcyXKdA;`0Bl>jr-G^4rH|)Eb2a5(tEV5|5)|p6aSxd{C__4|BG4wU$6TA zX7&F!YyZF9^#9%F|L?XpPCwl|^Gw(L^Zko2PFi|t#;PlG)?S;p{`%6*CzoxzwR+c` zDeE81+4^|yw#Q5NJYBZu>H5RZ*B^Pl^YrT@m);(^^zO*zcjs<>ICuNQxmzD^Jp6p) z(dQcvzub8A<>8BOk6wOz{r<^q!!?3UNI zYlpltPMVWIH&NC$hx=T~=6Z*OE`Qk9Ua1V#7k`W(Fm%IUW-q9qf`YjAQxmA^u3Oti98d9|0+jlX(OALUvAA z>OP4tc9)NaaGKX_?ZRzWej2HqpUIK^izV`ty8kRUV=doZA<4&=2Q2oQDrKZjC@T76xko D0;wQg literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_print.gif b/GUI/App_Themes/BlueAndGrey/pics/button_print.gif new file mode 100644 index 0000000000000000000000000000000000000000..dc6b96ec189d2d0582b4799e4c7a80eb93dc039a GIT binary patch literal 1156 zcmZ?wbhEHblxC1(_|Cu}tzs#oW+SiVtf1qjV(6!86rgSzs%;gkV-s)cnQZQzYUG@4 z<(FX_m~9u7ZQ)&EQ+B*4alIr=M<~ zd8TXr`I##Z&0c$K?%JdMi!V-EdTGY0D|6Ofo45Y@ip|FsZ#ubf^O@D#PpsW}YW?oh zD|epXu=~{7y_eVRyRvNCt<}5kY(8*d`=LvFPu*O4=>5L4kGG!veCYJ`6XzeEy8Q6; zl}AUfzPohe!PPr2PTc-}^TC_@Pv6~m{PoU@zmK22e)Rm!!)NawKL7aS<>%*bzPx_- z>D9Y$k6!uU%o6n*g&&khD&rr{P6;m0kc2*^UgHzTkL%@HAU36XHlT|BM zhs^#{A+Tsuy5BS}rmerOteCjKc0yW*MOX2&Q|8m=EYmW5$>vQ~T6q>zV{? zyBr_&%v$BKep!i=`o+sz=V@*InXuH4<3MVtnc?MhK6$gG1rH1+I88OFgv0mRLMIQ0cWgZTXZ;PFF7xHLo6#r4jLpjV;eL+XEt(EZg_@H)q!Y|4Npl z9effI4vx$`8WS9tOpd7D@H1^Z{=kpV?uLR-VNT)^eu=ad58GtEF*q_t{7>4gJT+xdrY_l7#J8C8LR80(s!=u?pBRgmc2QX1#e zt`(5He>O&Im@4}Y{TAJmnSbfxbErYwr>xc8>gRco_VHg{`onp4$ND3xPS4*&gFL} zExj~j)s;DGugzP3eZt!N3pN~GwDI`T%_o;_J+*A>>E+wbEZcT#^{zX!wmh1(YzJ#z5mi9?Sc-#>8q-PwDe&ffcc^ToGYK=kt4%a@N{y?XNW)30Zr ze!c(s_x-Ow?|=RM_W%E%zyE-MVH8jt0y-cQKzV_I<3GdKCyk$%EjZZBA-pT`k#gT` zV_zk&IUXAq2`Px&FmVi8viNwvf-~RFhYDwfl$?WB#hl#qv|ozXXHkyl5 zsSHl@RSsHYQ+TPVl}{rjLMvu2H%Zx(;F#7EG{Y{^YHNa;R*$GwOwW$4Vl_FN zvLhabn-890l#CCaAt2b4bIp3P*xI`W%FR4H8eS6&9x%4VE-O{@)ZDDt(fPs;b!5RQM7@W8O literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_rss.gif b/GUI/App_Themes/BlueAndGrey/pics/button_rss.gif new file mode 100644 index 0000000000000000000000000000000000000000..c49fae6d89ce5e81bede627f7c3d6c037115dd66 GIT binary patch literal 560 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 G1OPj?|EZ$@ literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/button_unsubscribefromthread.gif b/GUI/App_Themes/BlueAndGrey/pics/button_unsubscribefromthread.gif new file mode 100644 index 0000000000000000000000000000000000000000..d3ee18591382d60ae734245ebc1ad495a732a3da GIT binary patch literal 1374 zcmV-k1)=&!Nk%w1VH*G%0QUd@93?v+DnlSFMkFy#B{EPaHB~G-URftsTP9g!Bw}PO zVPqzAXDW4cE^{(NYdKDQJ5YaFW`B5cd)XEi;};j{9vLn%MB`N1BE9xvP z>ohawIW+1xH|je(uSy}SS3Cb$7{*E@@>L}1Ks)nmEB|RK|7tq_ct62DOtMc_pi6d< zXm8p_N8L$6#Y0)rR#DejR@PWtdp=Z#LtBtmW`;*#npJ9+R&AeMahqy-mu7jKO=qN0ZmwN(q*HIQRdTah zb+TT0wpVqzS$4Wxc)DGByIy;|Uwph}dZ%D_sAGM%VST%0f4gFRy@W)Aj9ZzJSC*@6 zh_iW*uWy%@Or)P&r=v}>sbZ(Kc%!s$hkbQ-xW`VtJhPr8kzG{WP zZHK*Xh`n-)y?T$mdy~Cqg1~Eqz;lekbdADti^X(}#d?pzdy>I>lgNCN$bXi|mz0*h zo{XrAm8*}Lwt|tPlaQH;tcsYgkdUL0kF$Z6yo#T@m6f)dmb9CjwW^Dwy@;Z`m!r6W zu&{`?m#C_bqrIH2y|JyRvaqGUxTdAGysf;xx4*gRjDoZitVwB z@vM~PvX|hup2DA~#F)LB?M%E!pj%irJ2z{l6o)zswL&h^~F|Nqqf_ul>e+`z@)*x2FD z>iE&_^XmWqEC2ui02=@r000R80L_)-wyj{nY}&>tRH!YR!H3u!b>W81S)_}SCNXO^ zjaoHo)0#1xB)vQCyxETc28@nU6 zP>2}u>ZYJGX4;NlDDMR2@)XKRb!SD&D6nIwVoODXby)Dy>v-QVWLtz zZ=vKUa%0A7=AmW;b)NA#)-5AD?8Pfp!$+Vtfic4c42V%DOENfc;1LB%z9Jle{7ECG zwQ#Lu+$cJeP9eNvxowmTdxr{h8g6%gO5Js%;m&IRML6Lg;`H;w1s?no3^DLr zVu1>#^s&bst_?TF8H#{I3I!Dm!3r$(q@xZd8RT(JG!1mA)t8ENL&O9wWP(aNr>ujH z9x$+AM;!~uSz>I~jIu%t68Hg1H*ny=M;vcdnt-7=&K1ZO5meztb!IS7hXMy6kiexk z7S+`nUR;4i7;Ldabt)KO2$pJ5Wtb7hu548`2CBZk^^785bYbkV$R?{S7Y`5s2p3a8 gAnml&R%`781_WS*0|N-)?YH2DD{cS)01yxWJ9&k`Q2+n{ literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_newposts.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_newposts.jpg new file mode 100644 index 0000000000000000000000000000000000000000..04973ae33a5a76e446c46c849292d6297b24e3d9 GIT binary patch literal 1109 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3B#pGZAC_A@4WdD`?uf6>KA9=PL{AWmg zy-$AohAnOP!?#|3ys2XSv&=Q?^lt~;td(tTpHU(IkE?mj%Xu0XEzC^6&p+M!}Bm4pTA5rng_m9}O{Ab{|3H{A}@&o^Y z-jBr(=XdX^|EPTQzQ~(DiP_64q91*{mg{+++=+qI|9Fa109XIB1u`TsWo D;ds=& literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_alt.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5df16875ca3bce77e21cc3adadd567c3f3786782 GIT binary patch literal 1096 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3{vR#(PzxTfP<7ck5j`cmC`i>;DX_{QEC#U8|PgBW2!Za-S{h*8R3U8o$=J z+F5qCiPLR_@Q|+yJl(sO^)pPb|^MIa`VPL+xoOE7kM9Cq5CjeeAC{)hyN+I z`Tkp4zs5f9%zuV0_E*op-RD=Me&z4_Z}r#zwr~8ke*3qwzvs=b?Ogx+?*6hG{a=@R z|K0v~?wdsX>i-OxweGX0t>5fhG;59}MC{aE|q_R%`qAKj16 zcbVNY*mk)_{{g@FOFN56mwhh3u`zt;oVhygwVeFLi~8@-{u{Ti(gyxJHGnC-O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA34)ooM8X3ueBG-Q-(#iU`sF_Bt6$IC_GtXt z-lns4cdoPdb(_>jwc>~7$?Te?{Wm?T>$m^($ZI)o@^u$?oy$nxBh__JWMj4V{g*on z;-dK^rxksSxZ2t0^V!pVR`cP{?(AQW```S{pM5gr<^9{Ag6oov+tHJt_j%uA#UNrx&H1KOYZXJ8V6j``y=^Cxsdlz=E~~a74DTnJ9cE3Z3}BY zGyU^#mmkjm8CVT}{AYMv-};|{&&KyR_x=O*%x6EwKiuB+r~0Gx(fJ~|d*XAK{fIsw zr+=xYP<7eN#sk3bCs#VX^z)>^snllmomyd{yJvWs%O{iciVE+*g7UJp0TGoX2;T= giu~2<@+z);yLbN9@9d(TtJUAEKk;_|p8Eec0gmFlssI20 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_locked.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_locked.jpg new file mode 100644 index 0000000000000000000000000000000000000000..39eb57e52692854d4ec275265325c0c9d4a073ee GIT binary patch literal 1147 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3cl^=w5; z7q-|lzuKpLagTIK&X?%*{6DTA-t@=$NAHRX?FY}hw)#riRDa|;=c|6~+qM9^)epb# zyu9^3XZGgoS+#$rOT{%W$gZ>hYb|>yQjA;U^y;1IrG+=nN%U2B9z7J1J}tq}Vhx+N z^t43nfIha+=l%vOr$641wf?%oi;%@$YpyJeo;3gTg|i>Oew;C@?7*Q`nTroJ11GKi zy2e#2qRYfEbYbB2kSiNL9tl|U@J;GlWlJZsf;~I(Z%=->|M*${$Ip-6m#YYVz*8?? zC;8*|x9X2`s_M4qK0Gh@Cv2X4=f(Ch zqO+by^jxZ}_0$Zgtn+O=nYkit&Xf&5bZj=9J@!g(PNBe@r%^r8&2yvHy$va}-J`}e pPsn1%vQ;{MX8X)yE_7ur&FWe@@6Wk8i$ytidukkB6KwzgCIBDi(=z}7 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_locked_alt.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_locked_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a41037c43777ed0dc88f00f0278835c33bab1179 GIT binary patch literal 1141 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3E z4qxto4fAe$UD#uD`Fvqw`tsLOb51Uejfs-p`962c?s~Hi^Z$s%>aN@JH~LZD#AO-# zc=vq_>wYM`wcmZR)5mE|b&54^S89YmG#{0k*UR2#Q<+tAUOMXL?X#;gf?^|H&lA2b zAA4E;9u*c$lYBaZ$4{HF>)6v7URRVG zr&eA*qm}yOjnwL|C#*y@F0D4z2z#>p(--5K+L|=Axf=`?x|>vRg`}+dn=R-yO{teB zG$W++s;Q1mp@_CcwPdx&xq#j|`g-=?c6^wAoS*+s?vJgH?(_fQ-27wZhwI1oZ+_kv z?tMMj;UoJ|&frHLAJV2jn9u*m>S`VTk9e2qk=IJzi+WwMTe#*w!y(7zFS!?Zu70`e z)a{6~wh#X7`4Il*`frDtuw5VaAO6q4Q+FbY|IM%M`^EloRxFOY{>SpS*^lcF$~sFQ zoNwD_vi;+<)$HA+=S5Ghj(nx;J>7dlJa1(5E3v3O;pOE5QL2Ai|E-kmKbp4lnzG5f z_#m$kx%kNmMNwIz%T;ykxcPOA3wL!dmvK?I3|lPr;Ca~U-Jvr6`J7G5Tl&;AS9J^b guJ4_0qBLt|)S{K?`;C`t9CgaOO1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3r<}u{ikRf{*9>bEUmMZe2Tf&#iT>s#n`~KGZGz zde=B0yI0@&g6Vy^x{otbclyP*9nf?)T^%nvQRlX3Z}XB5lC?Q*!s4B$3%;&6&Z)Jz zEzxGbd|R*on!`6j7JC&3^=1eE(6Q5&>{#7VSm6=8wEx#!Eur9F$CN}~2QKYe$+_!d zOPrj=EYXvefB?vAO15Od*2fh=8;H>^ZIr$%@tNzG;*w(4HbG{n6&dP5QKbn1?yT<;*@i&bN|D9i1`!WB)^e)rC^@rzgPVe2vo>6Yc^CSDQhfV6L zgOBbOA1%tdR@HIo>7_UBZEJGBO6$g1pWfY}EA;Phz*V8+pZEM{5S{UC=RU4Qhp#W^ zkz;0@a%rVs=&GQK99wg@pyy8m7jtb`9r#F7)1ugKbMC51?iW+PY`77lTJhVfsC1*~ h$D*Do%J$hoUYSMrK2K4VSXI1f>SC6yUFrXC0su|@%Rm4C literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4972bf2b5cbd620d642517d3f3963e7e67a571ae GIT binary patch literal 1159 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3*NMmg~jx2?a&NA{jSzKebYA2u&Ox-$FLAFH<6W?R=p zzP!F|;?ZOq&6-`a;-_3*a{2v#hTs!Fl$Fm}=vzM0Nd6qZ{%J|!=aQ%H>}`kK1shKn z{P;Da)YD%wTG;i}l9h)gzxIecmvjp{aH-_h>Q6KNe3orK_aU-m!w>(}kCwN`oGM*) zt>pEiRf&&-XCCX(^t%{TQaiWe=(4GmE34<9kN+c*{*Uwce+E`n{~vnSkG#MA{=xD$ zrH}ag>{&|de>mAczj|0etE8XMud}A-Emk_N zFts~V=d$tUHg4l-s+S{7+y5R~wB(hIZPkp9{aLT{Ts3`N*Qcsy?6y9A_y0`*bKcfk literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky_alt.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9a38e7d57d2e7715a5131a9d36dd63ed78a22867 GIT binary patch literal 1150 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3h4I{&x&H~Bq& z%(TB{pOLLE^YTA~-2C(oQ_em0{8JYk-hL!oyz%~-4@rAp|6Bf}{2!Nm{le@hpZgLf z`8=8Xc&={U&s!1rHJ;~YcG#`9>FX*^ANi%w_ba3|Lo;j7B*%=7Cn5??Z>YiUgcGB>c%X+ zP*p#P^J@~8TbweQ#x{A`)%YpLpU-$BSKf4bY5Sqtcu^axXTfX3HZPAC4d$1cbIv5u ztE_AC;y164>6)xQ>wV{6?f(4w8|?qM6chh5upa!;`Ma`4=I_MP_r3esO!a>_|7Un8 zbmdEb$A1R?5(^vWZ}m6D56x%$dVlNfWvd^_OZ>?Gt$eib)whrJITcd&Z^JJgnO6T% zYhQCjeAUH&Lcq}V{%8N=`os3a{X+i^z5gJ8;B!sbkK9N5<^H&SOg}1}FA<%&Py7RW z_m}xHo|(%szsX5_Sh(ft`qF;>7cZuNH_rM{pRTra`LYRlU%6w$y*?S)SZ_vrosj_f6Bi98r<{!J>xMV~y6~lUJuGx&^oF+w5C>PAedb*MGD8M4htSrZZ1F nORn((eORz!rBy$F+%hHoTf4d^dIbk&-}Jntcka{o`u{fp)=9|j literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky_legenda.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_newposts_sticky_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0ed506cec98d7a0f38fa3e4d168829654c543db8 GIT binary patch literal 1150 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3JJ9iXT-PO{}9tJT6f|X`&;$L+2`A=aAD8xujH-JR^^eJl zANrNw^tHD5aGXeO^kK26yW18neLc_Uqh0qyf4*2>(SMuQy4Ef~z2>!9nfbJfN7GFV z@A10kb4Bc(`u=^SnCrB(8q;~t_2p+=Ig%RsS!2hQ!-)o4H2s;I7Ix2*5?CHA9xUpn zSJYxSd2Q?3P*2N;npR~iKS=zk)8?L)VBpQ))@u`EaPH&ksI{KQ_Et>^4cBz*$@E>Z zTuVzdk!{ObyZrK>U;pm=&+uUW{SSfG@;~&{kHp_T|KR?c&h<69KlE4DACmpgz|psS zNsY&k>V*d%$#1SZF;Do1>AJt0ZrO$(u`~K`{hNE&-`7zjn96p|8VALbLUZmnR2azU=WkZejN7Ondt&g=+TdCyU?7 zwfVn&JU4l>RJXx2{YfGk&n&VeEbUi2wftS&sui?S(#F@?FVk=SyIb=Y_ng*9HoRGv qtdqXELQ5iJkJaL{T9Xflu8h>rc;!BQR&ZeU&C@Qortg{c|0V#+70VL< literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts.jpg new file mode 100644 index 0000000000000000000000000000000000000000..01f4b80aa288ae77aa7a852d48f7b006344bc921 GIT binary patch literal 875 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3DhCwS3ZaZ>C@-!-qN33xXw6$;jS;}+UrSMYbm zKjnW{<@s#3Rtx6TWtGg!7)^~6gm{K&3<_`AEhx`KD=z1ig-ejoE(p>xSy z=VScg>J*lurJE!38`q`(WDfgi{zruWTh~<^&JTx=+}{}9{*Spr?ERzk!}moi{xdvc z+xc;=o$}fIhy4r{t9?J7%BbeU|1$cmuPt92d3^EF)h|~soc-4C Lbks!$`~Noq=r23! literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_alt.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..df9e9005762dab5201be865a6ac4f5416d9ee577 GIT binary patch literal 856 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3AGis)Q5GgDyQ0l zw%;@S7}ovZt*n;67`xD9=7k~gI{Pi#EEe)j$r_G9;NRX+?{zbvXo>hF{<{~2yc zJ6%btTz*yI$4T+S-hbIb`b4v(?;5>-_`Fv*@N>Gj@ZlAXwMqMYHr(3UJ~QuoxxISD z>PO{opa1qe`QU!5oZ{bZ8~YFP2c_DN^tazr|M-pZ~M=sy~Nqk`M+Hzm!_|g|r sW^*6-Gja1~2Y!@q-($BteBbVCZysMO1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3o>tz`m+;}-RQY6?;01S=zqJgFPkVay{OS6wdET}2jZZ~L<@2r5 z^q+evRJY>O-Q%;aJ>9!2e)jnjKX-p?{c-VkK#k5dlhgUl_M7I-|Ly!DYKpJPuQ~FP zNu!^ai>{d*z0mt@W$M}&Gp?N~O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3`lOMcitSAro=-&CYGFSgA+s2DqdTqb@`u(`|^3->I z*|oE*_Y^uBw{|{BNRs;uD`wLWvAJu%s&-JSCUN56*Zv^wH{rPL7 zA1|HWx~Fhqh5m!0KY<_YJN8NcxVwLg$y?#0`-SsL`9-}S>~(kkaQ*On!5YyIZLNhX ze=K(RsNSKkyKbv(TE0-`F41*!bFM`log%O~>*7Dnf2Zpi>@)r|2>$W@;NNPJf0IrB z=6bg){}lh2U#rPpUlIK+<45ZU`NO-;H`d9$njU91+vDT4&5x#E`SLgG*5M;o>TSzD cteaNK9qV>KD&xtPu3xvZ|1-RK!2kay0QZw${Qv*} literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_locked_alt.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_locked_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c77e31d10a0054017637e911c4eb3140872a81a GIT binary patch literal 940 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 Uu70_C;q15NscSP9$p60y0Ct>Y9{>OV literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_sticky_alt.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_sticky_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7b828f3892263a288f58dc9ea66cccef834e0c73 GIT binary patch literal 924 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3NSNx5bf7k7$k2m=h|JLHa@%dZ+e}-1m<8NZ>4C+tbn%|@Tt>r(% zgbhH!{{IXrlmEG`|FLcUCzbl6zVZ9xY(AE^|C6mK{1g1hdZlj3jIZmtUIh89NY$== zEH9d|kMH7@MGUu7u9d##c#=4G;%-X`8HRfGda3%P_#YbThu8nGD3AKj&@}0f{@=-Z z`;7juZvJ=XKSN7-X#b=C42S*Mqbu6q#&7sH`-61YZ{Pjj=6BUpKm5<|X1-)>R@lYb z-4Bo4zg3jk^`SD#^h?zn`wekgKj!|f{CBCS!u+9oM}5+H{y*#=+!lURe)zrfPwnHs z#g8L?OtjtKX2bYst@&}omsM=N%PWKrG#!q*Qse&cJ^#w9@7I0ZZSf^zYp-F6a_y?f K>?jTP|2F}6C|#!j literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_sticky_legenda.jpg b/GUI/App_Themes/BlueAndGrey/pics/icon_nonewposts_sticky_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fed26805929e44d99b239a03fe0046b382df7e8a GIT binary patch literal 1050 zcmex=O1eh5W8JGka znFSgDA7PMZU|?j0n9TqMj7-cdtZeKYoLt;M1zQCem>8LvnOK-vSy@`H|qMvW5}awt1(JSZA;@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76V zi>sTvho@I?NN8AiL}XNQN@`kqMrKxVNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5L zEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+ zU%r0({^RE_kiQrinBhSN@fe!F1cClyVqsxsVF&q(k*OSrnFU!`6%E;h90S=C3x$=8 z8aYIqCNA7~kW<+>=!0ld(M2vX6_bamA34+^Y_cn|DpflZ|nYt>-L%dXE-GIpTTYUe+HiN-yq)1{|u9L{xh^5{?DME{hxum z{hyThKd1i;9}E98Jel;L;l$Pd3}To6x%B^7nf?9s@i>zUc5)S^djcOtPv3ee`Pv@s zg`QS!shYKq@^A5fly_~Z7yl>u!|L`C`^>-X zCHEV4ZNHVc`5Xrf!MP`;l+{ZO*KuJ#t~awQ_s;-|%E`48a(*@ihMoyR$MbW=kc#aQhvy>Dm{c)Tv3&`&Y(Ze%gHO+?v=&?|rX5?^(Cx o&8%u`&&Xwyb(3DKu}N53sb$!GakZ!O)U{!2OS0YX9shq50BD-3s{jB1 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/main.css b/GUI/App_Themes/Hnd/main.css new file mode 100644 index 0000000..a5029ef --- /dev/null +++ b/GUI/App_Themes/Hnd/main.css @@ -0,0 +1,555 @@ +/**********************************************/ +/* */ +/* HTML Tag styles */ +/* */ +/**********************************************/ + +A +{ + color : #C22026; + text-decoration : underline; +} + +A:visited +{ + color : #C22026; +} + +A:active +{ + color : #FEF3DA; + background : #006486; +} + +A:hover +{ + color : #C22026; + background : #FEF3DA; + text-decoration : none; +} + +BODY +{ + font-size: 9pt; + color: #000000; + font-family: verdana, arial, helvetica, sans-serif; + background-color: #FDF9F4; + background-image: url("pics/background_page.gif"); + background-position: left top; + background-repeat: repeat-x; + background-attachment: fixed; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; +} + +CODE, PRE +{ + font-family: Verdana , 'Lucida Console' , 'Courier New' , sans-serif; +} + +HR +{ + border-top: #C22026 1px solid; +} + +IMG +{ + border-style:solid; + border-color:#C22026; +} + +SELECT +{ + font-size: 9pt; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + +TD +{ + font-size: 9pt; + color: #000000; + font-family: verdana, arial, helvetica, sans-serif; +} + +TEXTAREA +{ + border-right: #C22026 1px solid; + border-top: #C22026 1px solid; + font: 9pt Verdana, Arial, Helvetica, sans-serif; + border-left: #C22026 1px solid; + color: #000000; + border-bottom: #C22026 1px solid; +} + +/***************************************************************************************/ + +/************************************************/ +/* */ +/* CSS Classes, used in the pages */ +/* */ +/************************************************/ + +/************************/ +/* Tag specific classes */ +/************************/ + +/* Class for links which shouldn't have any decoration. */ +A.LinkNoUnderline +{ + text-decoration: none; +} + +/* Class which is used with Thread subjects which are a link. */ +A.ThreadSubjectLink +{ + font-weight:bold; +} + +/**********************/ +/* Base color classes */ +/**********************/ + +/* Class to be used in tabular lists to get a slighter lighter background in the row. */ +.LightBackground +{ + background-color: #FEFDF9; +} + +/* Class to be used in tabular lists to get a slighter darker background in the row. */ +.DarkBackground +{ + background-color: #FEF3DA; +} + +/* Class to be used in tabular lists to get the normal background color as set in the body in the row. */ +.NormalBackground +{ + background-color: #FDF9F1; +} + + +/**************************************************/ +/* Tabular data and form oriented classes classes */ +/**************************************************/ + +/* Class for an empty row in a tabular list of data to keep the lines in the table */ +.EmptyRow +{ + border-top: #C22026 1px solid; + border-bottom: #C22026 1px solid; +} + +/* Class for an empty row in a tabular list of data to keep the lines in the table, however this class has only the top border defined */ +.EmptyRowOnlyTopBorder +{ + border-top: #C22026 1px solid; +} + +/* As EmptyRow, but now at the bottom of a tabular list of data */ +.EmptyRowBottom +{ + border-top: #C22026 1px solid; +} + +/* Class used for a table definition which are used as the explanation boxes on pages. */ +.ExplanationBox +{ + border: solid 1px; + border-top-color: #f1DeB2; + border-left-color: #f1DeB2; + border-right-color: #EcDaad; + border-bottom-color: #EcDaad; + background-color: #FEF3DA; + background-image: url("pics/background_explanationbox.gif"); + background-position: left top; + background-repeat: repeat-x; +} + +/* CLass for the normal form buttons, used everywhere in the application. */ +.FormButtons +{ + font-size: 9pt; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + + +/* Class for flat form buttons used in the message editor, for example the [b] [i] etc. buttons */ +.FormButtonsFlat_Light +{ + font-size: 9pt; + color: #333333; + background-color: #fcfcfc; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + +/* Class which is used a fill in form window, which is placed inside FormContent */ +.FormWindow +{ + background-color: #FEF3DA; + background-image: url("pics/background_explanationbox.gif"); + background-position: left top; + background-repeat: repeat-x; +} + +/* Class which is used for a general small border table with borders around every cell. This class is used + * in the IP Ban list and in the MessageEditor control where it's used above the smiley list for the caption. */ +.GeneralSmallBorderTable +{ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #333333; + background-color: #FEFDF9; + border: #EEDCB0; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; +} + +/* Class used for a table definition which are used as the legend boxes on pages. */ +.LegendBox +{ + border: solid 1px; + border-top-color: #f1DeB2; + border-left-color: #f1DeB2; + border-right-color: #EcDaad; + border-bottom-color: #EcDaad; + background-color: #FDF9F1; +} + +/* Class used for the message header, which is the header right above the message text containing post date and ip number. */ +.MessageHeader +{ + font-size:8pt; + border-bottom: #EEDCB0 1px solid; + color: #787878; +} + +/* Class used for the message footer, which is the footer right below the message text containing signature of the poster and the 'top' link. */ +.MessageFooter +{ + font-size:7pt; + border-top: #EEDCB0 1px solid; + color: #787878; +} + +/* Class for the slightly bigger text in the description text of the author of the message next to a message */ +.SmallFontAuthorSmaller +{ + font-size:7pt; + color: #000000; +} + +/* Class for the smallest text in the description text of the author of the message next to a message */ +.SmallFontAuthorSmallest +{ + font-size:6pt; + color: #000000; +} + +/* Class for slightly bigger fonts than SmallFontSmallest */ +.SmallFontSmaller +{ + font-size:8pt; +} + +/* Class for very small fonts, used everywhere in the application */ +.SmallFontSmallest +{ + font-size:7pt; +} + +/* Class for the small font used in threadlists */ +.SmallFontThreadList +{ + font-size:7pt; + color: #777777; +} + +/* Class for the area in which support information is placed above messages in message view */ +.SupportArea +{ + background-color: #FEFDF9; + border-bottom: solid 1px #EEDCB0; + border-top: solid 1px #EEDCB0; + border-left: solid 1px #EEDCB0; + border-right: solid 1px #EEDCB0; +} + +/* Class which is used for the headers in the support area sections: Support Queue management and Memos */ +.SupportAreaHeader +{ + color: #000000; + background-color: #EEDCB0; + background-image: url("pics/background_supportarea_1line.gif"); + background-position:top center; + background-repeat: repeat-x; + + font-weight: bold; + font-size: 8pt; +} + +/* Class for a row in the support area in which support information is placed above messages in message view */ +.SupportAreaRow +{ + border-bottom: solid 0px #EEDCB0; + border-top: solid 0px #EEDCB0; + border-left: solid 0px #EEDCB0; + border-right: solid 1px #EEDCB0; +} + +/* Class which is used for the container in which a form or table content is placed. */ +.TableContent, .FormContent +{ + background-color: #C22026; +} + +/* Class which is used for the column headers in tabular data in tables. */ +.TableColumnHeader, .FormColumnHeader +{ + font-weight: bold; + font-size: 8pt; + border-right: #EEDCB0 1px solid; + background-color: #C0B2B2; + color: #000000; +} + +/* Class which is used for the description displayed below a TableName or FormName. Only used in TwoLine table / form headers. */ +.TableDescription, .FormDescription +{ + font-size: 7pt; + font-weight: normal; + margin-left: 10px; + padding-top: 0px; +} + +/* Class which is used for the table header for tabular data with a 2-line header or a form header with two lines, used everywhere in the application. */ +.TableHeaderTwoLine, .FormHeaderTwoLine +{ + color: #FEF3DA; + background-color: #C22026; + background-image: url("pics/background_tablehd_2line.gif"); + background-position:top left; + background-repeat: repeat-x; +} + +/* Class which is used for the table header for tabular data with a 1-line header or a form header with one line, used everywhere in the application. + * One line headers don't have a description. */ +.TableHeaderOneLine, .FormHeaderOneLine +{ + color: #FEF3DA; + background-color: #C22026; + background-image: url("pics/background_tablehd_1line.gif"); + background-position:top left; + background-repeat: repeat-x; +} + +/* Class which is used for the name displayed in a table header of form header */ +.TableName, .FormName +{ + font-weight: bold; + font-size: 11pt; + margin-left: 4px; + padding-bottom: 0px; +} + +/* Class which is used for a row in tabular data. */ +.TableRow +{ + font-size:9pt; + border-right: #EEDCB0 1px solid; + color: #000000; +} + +/* Class which is used for a row in tabular data which is selected, like in a gridview. */ +.TableRowSelected +{ + font-size:9pt; + border-right: #ccdee4 1px solid; + background-color: #fbe39c; + color: #000000; +} + +/* Class which is used for the sub name of a table or form. This subname is displayed below the name in a slighter smaller font. Example usage: thread subject + * in messages view (Messages.aspx) */ +.TableSubName, .FormSubName +{ + font-size: 10pt; + font-weight: normal; + margin-left: 10px; + padding-top: 0px; +} + + +/* Class used for a TD definition which is used as the welcome box on the startpage */ +.WelcomeBox +{ + font-size:8pt; +} + + +/****************************/ +/* Header related classes */ +/****************************/ + +.HeaderTop +{ + background-image: url("pics/background_header_top.jpg"); + background-position: top left; + background-repeat: repeat-x; + background-color: #C22026; +} + +.HeaderBottom +{ + background-color: #C22026; +} + +.HeaderLinkTop +{ + color : #FEF3DA; + background: Transparent; + text-decoration : none; + font-weight:bold; +} + +.HeaderLinkTop:visited +{ + color : #FEF3DA; + background: Transparent; +} + +.HeaderLinkTop:active +{ + color : #FEF3DA; + background: Transparent; +} + +.HeaderLinkTop:hover +{ + color : #FEF3DA; + background: Transparent; + text-decoration : underline; +} + +.HeaderLinkBottom +{ + color : #FEF3DA; + background: Transparent; + text-decoration : none; +} + +.HeaderLinkBottom:visited +{ + color : #FEF3DA; + background: Transparent; +} + +.HeaderLinkBottom:active +{ + color : #FEF3DA; + background: Transparent; +} + +.HeaderLinkBottom:hover +{ + color : #FEF3DA; + background: Transparent; + text-decoration : underline; +} + +.HeaderSeparator +{ + color: #960409; +} + + + +/***************************************************************************************/ + +/*******************************************************/ +/* */ +/* CSS Classes, used in messages HTML */ +/* */ +/*******************************************************/ + +/* Class for text defined with the [size] UBB tag and size value 1 */ +.MessageFontSize_1 +{ + font-size:6pt; +} + +/* Class for text defined with the [size] UBB tag and size value 2 */ +.MessageFontSize_2 +{ + font-size:7pt; +} + +/* Class for text defined with the [size] UBB tag and size value 3 */ +.MessageFontSize_3 +{ + font-size:9pt; +} + +/* Class for text defined with the [size] UBB tag and size value 4 */ +.MessageFontSize_4 +{ + font-size:12pt; +} + +/* Class for text defined with the [size] UBB tag and size value 5 */ +.MessageFontSize_5 +{ + font-size:14pt; +} + +/* Class for text defined with the [size] UBB tag and size value 6 */ +.MessageFontSize_6 +{ + font-size:18pt; +} + + +/* Class for text defined with the [code] UBB tag. Text surrounded by [code] UBB tags is placed inside a table. + This class is used on the TD of the table which contains the actual text */ +.CodeText +{ + border-right: #EEDCB0 1px solid; + border-top: #EEDCB0 1px solid; + font-size: 7pt; + border-left: #EEDCB0 1px solid; + color: #444444; + border-bottom: #EEDCB0 1px solid; + background-color: #fcfcfc; +} + +/* Class for text defined with the [quote] UBB tag. Text surrounded by [quote] UBB tags is placed inside a table. + This class is used on the TD of the table which contains the actual text */ +.QuoteText +{ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #333333; + background-color: #fcfcfc; + border: #EEDCB0; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; +} + +/* Class for text defined with the [offtopic] UBB tag. Text surrounded by [offtopic] UBB tags is placed inside a span which uses this class. */ +.OfftopicText +{ + font-size: 7pt; + color: #777777; +} + +/***************************************************************************************/ diff --git a/GUI/App_Themes/Hnd/main.skin b/GUI/App_Themes/Hnd/main.skin new file mode 100644 index 0000000..992e6b2 --- /dev/null +++ b/GUI/App_Themes/Hnd/main.skin @@ -0,0 +1,113 @@ +<%-- + + Main skin for the HnD theme. + + --%> + +<%-- The logo image as shown in the header of every page --%> + + +<%-- The link URL of the anchor in which the logo image is placed on every page --%> + + +<%-- The imagebutton used to mark a thread done and which is shown when a thread isn't done in message view --%> + + +<%-- The imagebutton used to subscribe to notifications for the current thread in message view--%> + + +<%-- The imagebutton used to subscribe to notifications for the current thread in message view--%> + + +<%-- The imagebutton used to unsubscribe from notifications for the current thread in message view--%> + + +<%-- The imagebutton used to bookmark the current thread in message view--%> + + +<%-- The imagebutton used to unbookmark the current thread in message view--%> + + +<%-- The image used for the print button in message view to print the whole thread --%> + + +<%-- The image used for the move thread button in message view to move a thread --%> + + +<%-- The image used for the delete thread button in message view to delete a thread --%> + + +<%-- The image used for the close thread button in message view to close a thread --%> + + +<%-- The image used for the thread properties button in message view to view the properties of a thread --%> + + +<%-- The RSS button used in forum/thread views --%> + + +<%-- Image used in thread view to show that a sticky thread has new posts --%> + + +<%-- Image used in thread view to show that a sticky thread has no new posts --%> + + +<%-- Image used in thread view to show that a normal thread has new posts --%> + + +<%-- Image used in thread view to show that a normal thread has no new posts --%> + + +<%-- Image used in thread view to show that a closed thread has new posts --%> + + +<%-- Image used in thread view to show that a closed thread has no new posts --%> + + +<%-- Image used in thread view to show that a sticky thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a sticky thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a normal thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a normal thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a closed thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a closed thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread lists to show that a thread is marked done --%> + + +<%-- Image used in thread lists to show that a thread isn't yet marked done --%> + + +<%-- Legend variant of imgIconNoNewPosts --%> + + +<%-- Legend variant of imgIconNewPosts --%> + + +<%-- Legend variant of imgIconNoNewPostsClosed --%> + + +<%-- Legend variant of imgIconNewPostsClosed --%> + + +<%-- Legend variant of imgIconNoNewPostsSticky --%> + + +<%-- Legend variant of imgIconNewPostsSticky --%> + + +<%-- Image used for the Expand section button of the front page --%> + + +<%-- Image used for the Collapse section button of the front page --%> + diff --git a/GUI/App_Themes/Hnd/pics/HnDLogo.jpg b/GUI/App_Themes/Hnd/pics/HnDLogo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2e7422ac146e6d8ce52c638b5ed6a3113523d79d GIT binary patch literal 18835 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 R8t2CNpM~=Oz&n4>{}-2_CItWh literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/background_explanationbox.gif b/GUI/App_Themes/Hnd/pics/background_explanationbox.gif new file mode 100644 index 0000000000000000000000000000000000000000..0730f0a0243e1e0fb7a448ca546887994aeb766b GIT binary patch literal 11063 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 M;7W5qaryr@0km^fJ^%m! literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/background_page.gif b/GUI/App_Themes/Hnd/pics/background_page.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b22b2e198a088fa1e633c6d6ed0552c4cf5f411 GIT binary patch literal 25269 zcmb4p^=N~cPLAQlYrp9M9Yw&EPNY2J`r{P5k*b{%qssr{C(AddOZYngC(HQb`J3|{{K>-2`S#77>g+Dm`pppz|38D-o8x~scfrqh@&B9U z4%orX**5+z=J_7}WCee=gFjovpKjpqz~520lib;#-ody-ICpbL=Z@^1*B#$G;pxWB z#V-D6_U35r<`{>+*txlLKc2q1V|QnKyof))GdRHCY423$cQJAJJK@>N&G`ZTWcB83 z1%JAEbFzv*#@(F$!=LTmob3|)e>ScQ;{WF%{J;KxdqO~V8z2(|2nm(>6rvx*A_E8x ziv@g&meB{XgoXiFqV!{eq5*axiK)qP$BU~q&?R7_?zI0;dj08T88MMpuC z0HBcag81sLwCdW*3{XdQWmn<(Q04iVnWl4;(K3I!;zwKiA-rW8@q+Ps&uOs>?!$L;&q%$_+M*zVb9~| zyofc1tn^|(Grp~a{G6}piY6+xho(-x2Tp(Z3Q3#wi}ZEKi);MqU!qIS&jNMbjjM>#favU7c;L3evcnvq%+?f&>}R zhY+McJ1NKpE|(AlENqB_WTslEJEetFTt{pr+24og-}m)Gv}A-oLx6q=Fl;10G``n0+=1{{$PUp zoe=XaT@OehsQCs${W(|Y0m`zV10uqnThvH{uGXKXJjw)yvmjf@hj@=x;%bcf0eayy zrBI=XZksN$UW8k2_LF{D7s5ZdYSMrug#C2fn%4}*&jKfThtPObM5)=INivwAS;p39}JnT$`Rn94+(`w zzU@JWRcg7_*r2J-*0(x84~(VA2MY}|dYXt@l0*Ya!oK_erela+jT<-t-*QiknSObB z`LWpezX##}1r`*2pr>=`-{LsH0bBhf9jx`z4SF)hF~lK%f8vK@ILwko`R>8BGi z#D@2+3AQwrIhmB4C3kF-mrS11xRqMpPXv=5XHTJcCDc%Mdc#pLBJ2VTn3K-;8EW$X)Zbbq#QI(Kem_g9k+%#hcM`UyZ9vqpTT- z@8hOxRyzJ8-#^QiZ28XP zGCtHj%9t?%jXn6+mzr|RjS%F5tHBZ^@~;8VYIW>uRpx^T+(YYK%FD*ra`yvSb}T++ zGEKZ*v<=7l%<7_9hDkW8yeoZl)y~}CeM-0&7#_-`kv%nBTwE3qDzSRg*e%u$5_99A zF}?4lrd4&Hq3FVA@umkf+}60CK-BQ#(;IzkvVk)^t`28wLOJX*OpBm{ib#_c)=Rp@ zS^;1%aW1dF**RmyRmpa?PgGwn7Jn(R(zPS@7SdAyNtORxS@>{k(P!yUqt7iPDk*zq z5EwRE%%kfd^h(_jz51}O*44(7H8Nm-Jf$T12_b&YyL*tO<|nt6iMCN>3BfN0^tp|w zHIeaiqT?z|w0OYnx4JX}GNPI))zUp}Mq4$SrKEbKt9=lo6#<2OZK1!}caQlgjaDh? z<^f4_Gov-*$gjf$LaQQ7%rng=&Q&e6#bWm2!V_DqzYB=MvO+%kG;p#$C*a-CN-k5Dc*Hsi14uh-6qf)yp(}WjNdls(T8?k``!;>KTX1yL{jkWH&M z9C)6$hm+H2@{C?IdUl@;N~}X=FhXZs=6mJ6QYU&jp#OC$kKLq;^GKh}J?~q@9`c{? zBiy7x%2NvATlBI-_{Fd9`4SmBb(=rz-Nt^px)%OMeS6J^qvRD$p>?5ikbKF~pCRfL zmu#~7aSc7vM(XAp9&Kizr$4F}v)#aIZ1eL;op)Qci-!huonFkKAINi<#wcWs|1vq) z-FQ}^)vz7<2-kY#ciiw`)|BfvWXRM`GUE5nMwX~|PN3i8m==wL@84*~O|&a9(X)DZ zQKL~m+Fy}>>YD@#Fa8~2-94BU_BI5kCsGFXG3@wN`b7Ov*RR#IQibOH6IXLDQujw+ zQkt9IVM%x3#?OkJxRwcZ>4_` zrMdzbeg80imr1o7w=~7NIUjtnKP9m}Ity4L4J0h^`&JY15&PTOJ%ESE`(A;!2+-n$ z#1|5FYu0W_@P)v)Fh96hIr#6H*WMTRKW72=+`SW2-0sQvXfU|_WAHg)^eiX!>t-;| zRQYurZuh;wR)xv4G2a8T=9&{0${_6uR{_|Nnaaud%jEl=beKx(S@fNG1Ng%3>01yN zgy_|VgKF%jYeGIqS-$Kt+e-BpI`t+_4LMG9S;Gbob^03Agk*<%saXX9CPH4wI1=PX zoRIz$uL;St4EK`p+RS&e(f@H{8B{< zf`=Hu9UxY2Iu>r2FOG~%o)Be+!Z6Tgr`<_)RIi75j-DkOlbZz-h^;pKCsSm;MctK~@%#hy0$ia8C+Z&^<8du1!$u3VtpdPc;?ttUJ)UGocdh&3zH0?~$+oPE?u#+0-T=Cqb&{#J2N9 z{;s%fRfj_Tc$>Ajl$4kgRR=k`WI2Oh#LZFE-HE0^&;vvg=}@wbB}t)viUAl@z#lTn z7p0E~S#S%~Q;MKF_lEN)nW-i5oC4%1d{f4g_sCPcr&59h%yZyGCf3O^Ot&cytW)?9 z;8)C%2?9~h7b#`@V4DkoCL%#yl|Wg|0ip&Vri(D(2NTCZ#MM&tIAbnTn*qVkZgv4 z)G&g1QqoP-2%yZKacG!2Qv|P7N{+z~y{xoZ0|;?5v`H)bDEz3_ycpg#yRX`7%Y4WmZAocMT8N5$o#U9{!l%V znKH(tJIS0m^BR#tE}Mg4&dIa3cD(>>bf=U}g?tY%^HYPAS>2LQ;9#V3kbv$CGB4<~ zbqd#J*5VXMZU`d1nM1k{P#}jW_N27R!q`Eu4GLdYOa?X$(wdf~XP826^T!F{aNmaD z<7VClB7G5^dBjXQGywx_X2UPMPtzdcm&uFFd6NX3`X?%y$q7lG)tA1~PI1 zc!UJ&2tslZknhbfOTm1ZQ+PDep*t<#5R}7(guh}bc!`7rVPHQHL;;jY7&0Ze2Z2z7 z#CsJ8Ze|6s6f)yrNJB{J1;ivRgBcl?i_CBo1d-chma6A(A)us&DTuT`nQJg7W@Ka< z)UqdQlp@3A0*>8C)#FUt+(5x?Qm8;kOP1Rr4J51s1EZ45>w@I;ptJj|kky_UKtYJe zW**$DI17W6!=%O7{CR}=GbxCyP%q4)%m*O~L1}+LUd8Q{X+S}ws38L5j;h3!&Y?5> zHd4vzkU%+j7Y;fmm>-USzwtt`rx(99%=_E}*FpY43zWMELdtClpBa@87^1pyh11<7 zHs_^Xn6fK@{HL}^$>}l%R^(e&_-{E>2|A=(un>lXU^Yu$*;YIeETn>Dh;LTDG%7|Q zimGKRdF3mDFlD*wl|jft3ERR$1WI?Sl2@ZlOTPNTtGW#Ghkm-$-l(ix-N8`^j+jhV z6v_*zL(HMeG+1gv)3Y{kx0PfXm3EsIz|D$oLA0xP3CJ_!heo!Xdi9oU&Z#<@%BG}D z5TVFYlWkOHA&+sLF3S=^U&>*iUdS-kiloAt0HbmWxw=GFq)u;@g;8B~VO?NvHt_=S zGuygQA-HHA21$X@j;l+HtUZ&f6`-uoVnGkfS5IoxxfxYxO*c#ml{eRwC1{{gwix%w z`t`zkVegtHsz&GO%0ch?ZjGiXBNW!QK4F^Vi*40WUE^_jQ?hNvarz$$n|dO@k@U$ZuKZV}T9x3Kxtudos^+qLl26Wkir09l9*)0?$= zo96_GgA7~5XKtHLjT$BFsw7@Cv2L{l^|U^tYN4~M=hq~7s#!-*)h5x`JZpre+HaTC zY-5#gM+kHrMYd9z0=hIhlxI3jt^wL~MD)TP#LcZwqneerTfZ8&xM{SWT(vSn|J;YR z)fLt(Q?)Dj)N4Rnbd0epbq&eWogL|IaYk6;AriX!mN2%8AI8`ZngqQ2?WT6^9KxN# zGhOAFwpZJ22y}}9TVaGO~U}LETYw4FFOP3}1Iu&GfvcZZU**ptd`zH9H;|w<&A3{pf4ov#amB z?gDNTb3zBdz334$1w5ncW{v8io9Ut==sTF{KnV{V%VRI0?eC4db?vakT0@tt9VTqu zZJO=vK3(702ISfPzK$A#qIwdbkRNP+Ir^{(eSNydEg9GC@!MGOqV{UmUbXrbF*>5R zY(&B{JwUcX-mDIC*pLL<;9I+Tm7+d_7o%ZzL&|L3ikhvM?T)w6-EmPvMl*w~JHr#k z^+5GrUdN$7*X<=yEd$$K2ha{G&bB1sZmJ=YAALRK+v69S6Z|_9%Ju-@_UL1+G2Iup zT^BPXgI7cLJL4t+L!Pj|`o z&7_`IhW1~ujjU>o{fVA%Xc*+48K0`3(8RYZi(t3#J*B?G!otL_pZ0XjF2wcCn5FlU z3ll#UnJT94&@h=(-WiB_F(TC0D&H`84>lEZJw$B!k5v>KU5^XV8lt}*JTJPPFNF2W zi?o~AVL9yjxMt`7X%1W1{hNKU^k^3=I=6VEFyqjG<9C=_*y%FRn%~==k`q~^upb%I zT3~LNK7QQ~m3GCghqQl%AL}>~$8bxE=itP-vEr0A*HE3I=jAvYST7EXp zm*FRz6lb&p*39kx1#n=ii&pn%`kB5?{B9hc*xnp#7;VW|{R5kF!LQcP&aq~!1lUjZ6|esKI+t;?p*wK9Y(21yELw4G z#F_VP8$|tEsUKX(*cnsY`FXSQ1KNMhy6^_SM$fs`xI4cly5r)zY8f++;+UqsX=mHt z>e|_sYTSEfzq;+PYJamQIj|>Z51`N5py(&mX5TJj-xvQdq4;5g`rcgk*ZpUXdn`=^ z;tNDn9|(yX7fDKXi1)?`zY?-F6YgrSx%O|0HSJNE9=-276n?)tqCNXe=}@|n;L)!s z$juPb`vcwuBC$u^OoPV`MTZAp=j3;e3ON=i`VS?=h}oOg1$U38UYrmso{-S)mf9cv zw|8VXxF{t?eAaj_^!L&ouVVJboR+Io2e;Eo#kfG2NcK?rk+WoGJKk6MVa*eSaALb-!b0$DyAv zZD)%;^Gu6<;hq>)JZobLbyymEVyS(W;jqnkd!(^DEc7A@MX_Wrk0s7mK!tKeKC^5;S;{ckQ!I)z<(-V?=R}#NgL+;_J#juJ) zXY>n1;!5Ysv4<2i@^jAM9{O44Bns& zMP6R2;1DoX{_B*&1gdA{8Ral!T_G|jF+3rrOtCs%u{`H>Qs(Ph1U)z=29As>SB$8l zg2ka46oF#{gGqXRy2y-9lUjAsgDmh)T1UG4gd&_~sx z*Q~O5o1~fYX#59VN`qGmPYQU~d2qFVAIMuR1wD2qefp8d==Hy#X;zmlIA&V?IX$l( zIL|7Rf$Qog)4Y(z2&ehyRCfVB*9xG$aJ$oAt_flLVNF4;!dqO5h{0ihwasqS`y3l< zXKq9G?)f+3>4kOzP&&I$5#t)2B`)9Aq0HHzy6($zSFJf;>h{R;^-e)I0y~t|Apd&f zK!MNg}-(*1~fmz;3@<&%>B>ef@uhm)$wU>28`Caa> zIi>Z4Ltg1abfwEfD7d&Bh$Oq;mJ(XAF(ULFR z(5hT#u!w%&TF=&%U%-X6*d$-yWM-AT%Fq1{Y}G$w6`p*$?JkI)=|d@RNF;>AHWSH1T>VqLrapnS^yvy&aW z1!HSF%e=CAN1B!fe-lqIpJVb=j^QhE#qDPEB=OI;Y?66wFG`OPL{CNzl|TKqiuuIl zai%u)fQZ=f$=R3JPe<<^@l-|8*05E(OYO{@PBazu|C=YScX4*A{Ja-Ypc z%Y{U~-S}|g!Qe&n;5J6tG>L0l$q{!SIr(YIL%iX4FGa?SgZuI`b-}W+gOvMxQCCkr z{=knOydSL~!vA{ND8G#v`5=F7@#NF|)$dpc`!}hLGJKy)>=%W&!-l9zh390UJbdP_For-N;i^a+@ZcFTZ7~E^RKD|ooR%fVIO%7I( zUkErx^1Y~z*mX7RjXGXURq7J4_hT}8eF4BS_VL_0QY=B{QRNfmaD2Y&i4}W0xl0A| zdtV@tt;yJ87!sLX>OUnvL;Lw$x{>_-CvozYH6|{}pbkgLZCeun^MB$8(ff|q;6T#U zq37cbqK=;=z7iWq*ZIHOmlm;IoDO2bl2?nGKdYFgwUmA{iQaWCsx$6ztF5KHvHu|= z^av}H(5RlZ^NrvDy0j=$iWDjSMSMSp%cN5#&}7&5wa=K1p=BMp;gH*_%FF@v>dx1@ zbj~;-gXR$U8?i6;mK0F%DTBLwAlH+aVD!QLWB4dbF1{4dbGLvIr8#)=3uLR!dI^T2X5r&e|0~-d$#KS#5bID%iSLiqo zlkM5fb3W=$>y;hNF4{8g%LS`+;d?V;>MfT^*K55(bUaTg(@D8fl-|)gC#qLkj(1J< zQ?gXrd_DSeLhRA>dR)ZW)6Pu>!b0CcRomM`$WQzRC88)VKQZlD{Nf0W5*l0h2mA-k(JifolPS4P0q-Fkol zUy5u@M^bfL5=LBUB@3ls7pgWE_j6**ZrS7tDK&2Mej~KseOE>x`nw>yApv$a>I$g_ zw=~09M%>#L@4cE3!=Gcs#~?dcmWeI}-BRb}#br13fjGl^dFmm5-lR59Ol!N8W$vt+ zzqB#xi_j^>;CGaY3`a(upOrSv+AGLY4a`r5oi=Me!Rm*^zwD_qchM5Ukj z0YhCaiI}86DIxh&ru5m|$Kh?BQw3hN>E`^!Y%s$geK~GztTzPyBo}i`@{+CCWYO>o z)*$9JchtT7y`aH5Qw|-sHk#r!+S{MTq`?@;)|cakK?>L3w?3k&*EBX`oy z#q>0FC&K(eNo~`MT{{PRp%pTpfFAkneKj!^b6K&m)=!PX;1*~jU~ix3dssy}^R>Zi z@!H>?GmKN!x_{7o@}wa8VjKPd_SdI+sx5$*FSU1jmD~G!kAt?O-%g}89wQ68_B|qF zQ?SwpU`Fl*JXcg;lNB9d9;NfB3TW#4?%l}Jt%xo2<=Xl8U=7l8omVdRzTt(M?gvf}AO*p%nZVxmhNXH28dS1&Mx85<59(;J%(rKCE(jspG- zOT)_5Q%#YZ8gKAJ;25dVHP|}h!3^&3^sEs*<5UpNyzqUlrtWW*x&MU=bH@}yq8!>iD z_vUZm6HYU3zL#qrU}>MdPU1-^4^nck=i{UfSYm%N!lDU}qc6U`;lB(lork5Zb?6*m zU%Z~K`GCURSl9h7!rV^IyjacxmsD)LJBf$+g8e5*r5FK^&Iumr`_Jn6@10r5TmAl= z>MaEJ$jh$4gTN}@LJ#Z2Y)DgIHBF7ll*z`%k{ADlL3^#Kr}BvUj|5L8ooR6 z-5BVm+7+rj2@E<9XZHwu2oKjgC)6)MEu z&hP|yC>ntN-}E|F?Mb-OAZ7V@^PgRl-^qC=5s_ zECA@2v7Xcqm!*r};{(Xy>rHpjD*NWHhsWU=TTImMK!jAmX`HQVB3Ig(->iA~dl!xda$XN0-dxnC!ru ztQ_H>8Ar4vlUzBOGzX4-Ocx&kj2{E1ZU7@m3{u@Uq7}~rWztfW5m9sSfZ5vQs`F$w zVB)!Id~;W92y=2MJf^fOZ4gYPH1+)vI5nciyZJnlP6?9U4cP>y(VZfjq*hP{*B0bL?EMFV% z+70dLf@o$%zrO%6O@Vtnz+2=|Isr*3-AU*aXwKb=q@`YYCb_4jQV7KKcSSz$g0j1% zRIMle=Lu#CNXn6k`Lzmo)gAfNGve10cz5Zq4SJC_|v1 z(lRVOBl88KmC!jtmlG8Q))VW_lH_3k4Y0`o z8>X3DWaFj~MXAtIV5%5%QjtMA7=(CZ81umkY3mgk*ON7Fg`iaeP{tokA=a4l z6V>zJ$N~mI6ty5ch_WEo1_2X9b$eyJF~|v>%uiq`3c;nIn3G#=iqGNEGZe+S5P1K2 zaqT7i5iYTuGM*Zev3r?uWSC3fRiL?f=a{s-j;f<5-SfK5nCZ^r!{pct0FJB?-G;fj zhB;|oNH8+57*q0xGG5RSwMl_;N0uWX1ws1dO^BSCh=LE03>wN}N{zAzuZjYeqJGsP zPtQUz1JoPuN*p4;P|tP)k`7_^WR++=y~VxQ00jZ0X`QN$kHW=G($u<;dB(W z211o<6bR=mOy*N+LtsvNw^0<%OkS^*S$175CL`4Nq3htLel5)}m}sBCIe9R#*8_zP6UC zZgZnL)2JSdt0JC`iubOn*(~GHC>1iSwS^D`^w!A^p~JTbWjX730x-A;44f6UM?s__ zgp~2DwWTb=QK5<q>7g8rE)RwGP z$A&6pfTr@zz&IAFU8ve;JTb2X+VL!C61Enu^i<8>=EcH#zUwAPVU@pk`$M0KGO7|p zWMX-5^=M=(qPMaZ(+IsnKSSN3->KJ$MPSfWSPCD^x)5O1sIoQ^ahG6yI0Fl3ZPTl7 zT)C>DwL{oz)auLCkw>-U3pK8@Cc~+STDGe5z1z5`n?33q%WSJS*pf0M5u2>_A`8_m zMgURj)*y{bl+L{~HXy=_F zP~W^V-BAr~t`crNG-~vU>dZB)Mc~?4e6Xc`)qE)QW8u2m>F#p7-g2L|D!cX}Hq1}q z(t^51@OEkF)j;yaZB4#6hTIOl&Wf=TZen}U@)*^Eu}FtVuVSlZ{1Ad13L`a zPBXjj@Cs`Ww5~shy4#;M`Gv@+3v~|+6~*K;O77DNoo)czjijX4OQW!{^>t67wTumo z^d{x3Q7w8Vy<74vE#6gp#=UGa)wFEwFr!{XT^}QAqMCY8k9x8^z0cbhtlKa_`=U12 zu6-XhEC%iJu>V`8Ir)se{m1NIhu-F1yKxv*H+O#v16vzwUmr@Vr_2cV%pS*}*~tb? zrNOt;HrzI{)emHE57-NJ?y-&Vp~m9adQ`TD0;4AaG&{-I>oN-)yV)oE`_OOMM>kn# ze0`=;*?R_xa7yg$FL%1x@v~p>gJkxD%|fNiI|JTYqhEG#og&j_Cc}KjW7+sY58}sOAzd0A$>~G(~V^W(tTb*q?e`q_NCfvxt)^o#-F{i-=8%=-m#Zul( zJk#ncnypUpp2SjjV|}KuZ0&WCjnKly{Gvq*kxq7d9B+TGgmzCmYH`D8U`2DrYzNmT zy!U+Z~)%fqKL5)Q-2*=1n|!o4WmneTE7et?|z zcJy`eppo`yN%VwJ=Gj9s&)ETN_|%!222zvuDvn=Fc92ba~HA3TPOA{RU9Ko(bl&F-5rW+JaH?%4lU}< z3+!6NOrot-#p`6g+X=;6fsK=6_^lnyoj4S6fyNppW8q=I($oFz;o?OOrM0x1fkoPl z<=G9!-RWEC!rO&)EJyp`?hc#gnn%VK$A_&h(VdS9W4XdR>ZMx@)EiYXYt+!&73vb= zr>2Be+Jp>rZOs1IfPvk%x$VB|L29-Gk*rN6t)69v-GG6EZS5Tfg4F=+1EO!cJpR}M zj&`PRTP}VFtk9JJZQ{kbUCbOHP;_yZ_897Y5XZ4}(YP;?b<{lNeBTof@2)f4Td#9C$k$q1rd=Tqs1HuJzZ^RhH{t>f#~q4tIE-f7RTBk;hv^Y!5xEjiCy4v~i<98Vvr zKV=Z%dH9s$AqS5-=wV`LY!nX%hdKj8;#*h}ERi7=k;G9Ll^p_)V<_Tz8vBspZ4E;W z8l0J(Q`wA&O+qAwsPjap6sf;OXXlEP4(FiXwjvt;2FGME47Rl=OpVuObpGuEPnXB{ z_oKrbqB0X6^1za_kN-Fy=;Xu>b88m(@l2m-OqYEaiHbPj}>zpjQddRuM`NvvB!F(Dk&Z4B!P5Ga!1cmau zw{=*_#A*>%ac?CR!K6`CJY2i-6Hjn~?XZB!3Mso?L^q_)E&_`OwbOhZ^>1j8d1xTa z+FeXJkuZbq5jM&ala-p078~n!o_gHYR$ED@X5G&{wJcR+3AYltZ|_r6R#@A21^iF6 z+iek-4d%$C8q3*Sa?1KiE00Lx*YI6h1huj-!jbm$^gnby#UHKz9Yr#PMwOy+)Q5x+ ztvnz*(W1nc?v0gY(Co>@#~^k8T4ZH>Yx~7JsxwKnyT+DQ={HeEiI7a5 zz33-gYRA^OixG_HV>y1pl<<$Clc=(+`;T(6X-H&2laD>693)zZWept({j98#a>IB( z9dY?gIzH(M=ZBD+yfyvwlQ%lh!Gw{Wj9w*-KnY6oVfpHeR>faC#G^KbF z-urn3=0}{?#^-$+M?98N{lc=6`ogc~2~_pwalz9E7DRc$x2Ec8+y&>lg64Kk#eW~? zCqF;it{Bo{T~SU+Vn(IqC7@R&^jJKLJbk`wB8wJMdR7yykr6x43b{IK4Os_`_F}!) z*0~iT3KyFVm43hoSQEE(X+?5O8gCL{3u6kqC`Yd)FFP}=mOY}RUTxUYvgK`$5T!7W zyx@>8Z<(5;dMeFtmR^_!-Msu+OtYs}mPg2Xbx=_}ESv{LQ}=GBmTW=`o2#oKhr@Zi z{rROi9NudUMfX{S+hymdTsuA%_bz5v1ziai6wje{VeG{k5=n~gMZ1HP?#2>GO?ic* zRE{l5zKKJNk+%~cSe%@vd~Z!$hFhe3fBRY(Tfcg6`=rUHeJZI?VZU&`%*y^-}YZRwd8t!rf=YS5p9fM?R%+bE@zC!jZ(FnkG3()jPK)=+vcAP zmL2D0vhPM$PtOV_ELKbv2I(PZD1`ml#bNvTmbIwp0bQau#-j^)rMaH(4fa`P^0`T6 z%s)oi?p=aAd9xbTnH?Oe0LGVnr^uDRn(yM%zg_0nwCHigc~InX(u|q&9=Jw@A%*@C z_no~l(WUh1xmp;`DG++H9P5{;!#Pv#{uT(cyLC)InwzoXZ6Z?tFH#z{n6GTrLF6pr z)21^)p*5lOOfEX??{5f0=BV=hMkiA~?re%dZ2NPTk1;8%#_VXBH^j8tKe>go|EpM6 z;C2v=wMQ+k63D8&rgZ{}bI*}TmA3IAnt_=6gzR@q6gLA5z&6tnee@Y>7U-;b-Y-AqkXlPeO*t z-;n^b7Gh#hm)354B%eeOB^3SMC;xqL@+~E=fY{k!>y%UCdt{4{IRy{HeqtoIv6Vo- zwTiHILQ2k)^}?`jb^VMA?<2PLZv8k#`pKh2Wu{eP2CrTg&B|X-G&4n;tlz`RDIqX>Uold)yo+iuHec-ft~qxqF-#pusoMTtk>HSQ#}ugD||Z7%Evz zirLVyc%W%R%<%c{+bL@68O@rG`OQ)B?~dGcxSF=j=?TodzmRdcVUp_eDqI*maq(&msC3Bcb<9ly3%jMrqBep#24?( z-wGHi{uFg9fFBn=aIG@9f9RZCB4K|k`3$5E`DzNzG28e&A7N~``59cEYyRBx@^fIh zQYw?V0HdvAuer@wg=tZsiqJcq&CBCNKP_H%S%fAir>0PtbKMQ$J%FawOc_84Jr5T8 zpp8pvgeQx621ZW%-gg0yYOa!kF(cT<;Y=uW%bndw!(7n4ZJM25%lEROeAPX>R%_Ke zR`$CYQm;nvsmRw}x$k$UAj{nM;HL={5AoUWWI)lVy)U#c$xpH?-<;6G>{`2S?l1&n zY~{;79YUHQgZ+B4^V-z_cmKUivEMrZ>&~dDZ#I>v1^J2(wte6E3eP)}X?DT=8-ql) zE(LD7B}u6W%__en?E22yO3>}}`(dy14)daw&qAy}X+Q&Mn>)6aHS+)D9x*k-Osp(? zd)^x;o+Jkw9c27|p~*L4&^Yu~G};6;=kZm)CMSPGNX*^vXRCCR(rLj{SCRSlFzLa~ zS-T{{{_gLBsg)NM_I?`Pru3|G=qk2~Y;$8fEotx83=-$WEl7X4)Q9nbQ-rcveNW?} z2d-(`sibM!zy|j@w~{;icQAgoZ+x;kv+*>=Rp7hNFUDRhsxV0*@}JC=%S0yX$oswB z9#iLeU4*vXx5SM>o<~yCMDqp8JBDV|o#*KOd~=JuJ|{bINTnF*ZpxG0sgx$YWxX~O= z%t4A>dLP9&A6K)rkqjQWZS^=DW~42RC_Zi1qCU8$g;g?_qCs4=F2d5Y>-qF&Soy|4 zddG$h;XfiYAT;phjd&Z{b$%>SjIjj z@vpTPX0mIW{Q>LJqPshC4GW#8Yvme7mcVI=gWr6opl9_#e+x}orIlR#Bq8T4@Qfn~ z4h5>~-Q)2yBNFMj`uQhX2To)!oBU!G*A-r#uM4ps*Sh;o2#H*MN>T1N1nrUf&oE~J2t6#Gx%u+PX=a3*x4HZK=2=RG1$>h7 z;_U=T@B5|mdFF=uw5#|@$7yyJxaR16IZGvskhT!C@bfzhyjKtiwe*vA^!dByc{c9v z8~$Bs&26iOkgUr|?EL$liubDfFEVo9*|*#=|uqy((&+tF$Nf{dy-ih;yOK<0{};<9)B2p z+0R4v^@w85`~d4ZW?+v^mEb>&?hWq0ucRH!lRYLUoE=r2B2~?X3cSR?LGm6%TY5oj z(!V8EJp}k~9rmhy$oYeG*5AWAJr5awi&=&GP6QP(1%z9MzvT-cf`@x_0X|sy5rV&o z$$W=d2JPxu|CVttR&_#5y3@nM$j(7*Dxi8G;7ONtTGGS9KA-(>uP%E>>)BtYP zK&Lamm-=5a!aaU7`k2XlhfD^Vk-O8W0Npx5Pip*OdVvipAfTnrRk+96M9@WTSnsNi zDpO1^pFcT86jm?r{+Dnr@a8?2LSD72>z%?&d+%&>2_66yiu0cUBPH-5z(k9t(B%U!U~fl?GPp2fKko zV_jj7`EI9X@JoiflhWP25nR)naP6Xc7 z2%o|Ix(b3%t->+-zpxXYSj$Ml$>fKs!R!&yvKD3t_kdw=k_;I*#M7^uKl!D8IN4Mf zQXmFX3ud(rkEls`hW7t2A{HMW*3g+sX&r_#h!7)BW{*h0s|2ZC_^qAArt$~i_@i6& zLuw5IJFR^pCd16Y-hIqBjX zJpTwABCR)*m>r32FW`QgIU$DOwQ7h8n{-bMn90j8b2DE`9e%YDm&KA?wF#yD@P`FL z*eRHhkAv3BB}U*pI|ad?Il)5v@EZ@v)64u1ox{!Wj zpj078Vhi<{HNpG?1l$Ic>*-m{Pf#+3L`8$rkJJm-An?DJ2x%n}pk6WaP)XG$0X;cj zlDzn{BXKl31q8`nBP*tw&NqX@KW8B|E`u&@kkSNYK7v_dhQM50-qB_8q)oxFYMB-e z$xm>Xw!BM_dLRW+#e(@!UJ%ZOQdjblNS4fE!-`PP+X8W_%p1W1HE-fI%0h+6l3}az zHLo(B$Wq`$#aqfMkQel;cmBhzyghdm5(6OjE~e+NxbiA4rUZOeBH1G=<6kI?z?9T_ zR_^iDOv)5(5T3OwUVE+hIRqD zj7uT*s`?^S%S%=KN~ki#u*P?*W?3E9YZ!P+S#~6s$SqU+ATsrjQ8le>3Ei|eCK8ip zSfeKtjR&FWyon!rm(2?nFL@QDZ$ba5BN+-&YXv2KR8^%^#UW}n^T_Itz4gC(YrBOq z8Ch%7G|E^n;eHx5oJy5Sk=1qHmD56{2&!8ESiTr*R1{5B!|DxDF)dH)t#vg*J}Shd zZ#3fc2##>Lx)j)E@j<3OA+OZVonr_ zbD?P8unDD6N-JD59$8a_L0y8--|JeaW<2Ss>v{~!A(&=KD(t~@TE;=rR7pu48 z<=f|RO~dQT%+}PtL>pth3`yPo_zOsUAc#GOMX3?0@|Fu zg{6q96`;oWvsLsSEcuZ#6p^*SOj?Andvwq8gQ6^a#$>N^W&}yeQ7mY!lOO z>+&Hkudi2)YNxo)K+H5uZx>Z;Hy=-Tz1gnH+pJQrZ`@#Q#>)3@`(WF*uud~w6f<28 z!qI=(2B)KXW~l4`*7s4(VAuQl?`mo*>d}fXx|FCpt@^r3>bs`x8up^v2^#tj>gw0~ zTIPM)SL*xoqXwsqid9kVsxw{mJKc}$>#5}b%0+d4we8N^8WfuyJY}mCR4C@z8f0o1 zjH+)@uy1mn>8YIldjh>3>bM>u#Q(KJVGz*H8Me`Vwz2sh0@`MR6=;8=@ZYzyJxNi2 z=k4mhnGBhT3@gn3HS`@4SLi*{Y%4d$P}q&(uSfWXhK8sC&PAkA!o7UWqY`%G=i6NIUNCBMQv#fLrOk?U(sX02HcVtpxk$=i)Lz2p*OE#GI?hx0o;-R$k`tJ#T}eu88C=(O?FtMsXG-?6OO$*X8wjlxK^$OI7o_u78Go@PXU zXBIX)Ni(-F(SXaD9dtIqK%?7_eaE7WabiWYr?ZpT{@I6(vy>dOd~_ry_=$Yj6i4GM zmVNPy$((rc{J!r$ag!z2hNU&%F>%rP4qpImOlRKg#G8SsGxmkZqFE37Wgu*!zF|Ix zeHP#_-5cHcT6DS4cY&jEWxL_7=Cz^U1c#%UVVPU7_`3YWZ&{+T|EJ>OXTRao{(tXo zNS@vFvkuJ7+0P3O{JWZ2c_}(gxjXOOxMD^CaLbtTz?1mXEQBkN`t2^gEnYvylThyy zX=$$_gm0JsFB2l{-EUssoDJy;uI9Kc+J%nc=Iz^(-sF;Q-YKS1Y2p2}pdlGv4mFKIb8B=e_;|-u(sJ?&4lf z=DqIYR^8`w-r4BQ?|Z)P+fMKOp6Dk)>`_qVCt&F`p5=I*>w6ySt6lGfzT}+l?-0K5 z{?6|oPw))T@b*0hhV9$4PUC?7<^yl#Fj@1p{>$Be2-k$P2-s!WB?-GvlrOop$ zU*tj#;qpHJ>-O&5Dt_tk-SFp**aLs*Sw8DgFz|Mc*RPJ~dyeU3?(!~=-VOlqcr0YMc(i(?*O^}>RE5^AOQJgKj=cv^CSQCDc{({zT`wt@V#E~ zW}o?`{R3eC=8E6;Sr76wU-7Tc>Pm0-O8*0zU-2p5@C^^~nlJLiZuY~!`9d%9-aY)F zkM#A9`?sI`LVxRvpYkK`^9!&1#(({Dzwp(M`dU8jGY|XC?f_GN{H*TX5wQCFPV%Qu z{iv`1^syiF&@c2+Ao=RQ=jA{AwSW8U4+sn=f((K`CqIRXiwrh|iG_ndQH+C&Hc=-h zj*W{Qh=r64l!=xRKd6g5p$riWiLQx`ijb)h9k0Kli$6Alh_{6i zn$M|-(I=F+$eRqrg4Keqi`ABqyMqywrh~Xqx67`l$jYw~&*G7y&z!2QnJ25?<(N9S zs+VZnx_s}BEvx3}TOnAMmPOe%NfD_Z0-+5QcjDP7N7m*I%5+Yl$ZoA#Svr(Wq_bD! z6bdFv9!=t5ijK?!58*!6OzpUGI7_;870Qw|r&G){H8MM>CaUQ`-16 zR+ch>QFwBLMr$S~t~Mg9iifG*V#5Mq$_=}BlR!tSG}0>++Tmqon7mo4E3aeHaEd7I ztu?QA!+Gn(ddxhGC{K6H_VSD@Z{nzb9jV4r3(MoEvPvm2-s^}MX{p2J>D=3CV`l8% zq`AZB6sS$JIt4$=%RUy)-i-uy;AG=*Axs!ybWU6mbeCCOW#L3jP6cL_iY%W1R}6OE zwekrM6P*%aY1M4y(tZ}M^G#9zJ;R)0QSepEdDOb)5O99Y8~Oil}*zevLG#WL0KR(LuPeKFLx%&RY5=6u$e%0 z(V5eNnX&fcbQgjc)HI7_mL^w*VYnZp&%h_oemuN*TA*1a2qszYjoMpXtF%f?LxbEY zo=X0Rx2uJLR_aZY|Ix^0sZ)jJrkCB7C1zx3>1Wf6(9X1_pkIo&*gTu{Hc_A*oz@6` zHd%O{VZ=dN<9^)k*I$CSLL*2AtWpx`w+m#we#;oT{Bh+VR%Jg&CeU z`el`{J7uY=D#ig5lNGHAcP;1BTfU2+qZ%V=sNF@kDrec@H7#_cTOydC+xkIyAf#HW ztG3454l{Dsx(?Go$1{g5G;t${?f5(mz-;J|Vb>kO2rAEQwV{P??r7$j3ypdN4Qw2{ z%`cvpu->S55X9`~jqoDi8w(Ws=qW#4c;j{VWFuAJ>|Z-ei>HIORi%TJuy2yVk4X6H5p@w@8uZ%>17VSkYC9tHoAFaj(7w-62)TIyyb~+YCQ0r&>FD24s_0QL5P6( zV79yfvWo}ZbKLnlM?BxfZhP=cRoKE)z5a|Kg|K^9>TcM82GD>8)VovRMi4vVbgpyz z!KnKz-c%v&|<~j#I8q_6*1+?JuVkp2y(g2A6iycw5%j%zAW@BkB;M3UP)o<{Z!txrUsggnNf`zv zPp*)rWT*bO6r|3lms;71)m7Jfez1iwUp<9 zifF%hI`D$$lw4Vu2s_C&5TEdb;pj5MyV32gh*&KD=xIn7#|Xxepd@@G34_4Tq>}JO zEB&DQLikbj>G4HIJm?@DXGD|khkngFA`{uk&Mc~rn^5GQJ+s+PfQECY+}sa0F?vd* z-Z7AXGiwUl`n@~SaIf4ePz;f%PC`yjl3A#4NThahco{6qQT<8AK1ww_b8M$jQCUjv9h9B_B%w8r`qWw;wT5ji zA{yf<&p4(Ki4?u2RP*{)MXt4ooXl%XP5MK|7O{S{gd$X*XHpd|w}jlZYzjHb((tA- zrs0fd36bjABIfm@vmEO|g~w5`#@C1rb!aC4J8IuZ+V;P@<8D+7s?hje@u|vfXCB*m z+X996zY314n9mZ|$ZB1rEjKByAZgp5^T zeAOD^BZl?AOgv~X{dwcEgjb#;{ozRCtGke1mxDr9E>CG1P9NiwpnBwJLVZkR6J{Bd z2aTyiH@o9N8aJUhHlmu#s$%68#kMY}N!vMqvZi{??bJdMi-2V{QySKQ zzOsaCS!`58RR(*7YM_U`V}hnSyaV7i6N`{wX0w``LgwhPUHob87TbtLP_mL4ylHO7 zchx{LP^O$@YzMz6YSzRcnFT%Z~TF!})JZ6LbWtuJya^+s=3wn+D9Twwl}Q z;_-sI0Y#tzzK_l9B~u*YrKaAyH;rLsV;tlqr+BJ`9P%Pg+~yCJHLqQr?P3pLqxR=PAh@~Tt%agr{N3;7rq;FSb1J+2>jUV!+8@qf zxcd9$%--G5i4E$j8$H*BuW~JA@N@P~p6ev!d|4&WYJzt?oO=iPr*mCpWw%}Q_+<8l zIbZFNhnL*f4k_0O&Uw)r9q>iKeZ%oRfTLo305S-4%m?7_Vy8Xa$R9hoi!XGzRz2xI z_c;@ZFM5J&K?bhBJPC`Sh30R%_*Ay_%9UOGB5>Zv8D~55_nr8s6CAEL7rJthD1-j< zKAfUQbe$J?=C(WdrgB)fcaOJh0Em7Kmv^gnY(y7)0@!~6sAl2TcKn8c8%R*AR(Q&VW@vBcyNhWh~XrJJ?L*V2zr6%f_T@0^QU@Rn1)2y zfps^BKX*iOmwoZ~ipUp&Er@f7M{R7!L@H={CMbnhSBTKJhi;gLWA}TUIE2lIZ?s2y zj!1_q=ylS#ea(mehR%nGyVrjc$b&Cfg&kOj-FS`G*o}htiUQb(lGuaUmx$1Jg!9*p ze|V1bSB=%Eh7%Zszn6W#=Zu@@i#`~J$7hB+=z@hPbVrA6XXl7oSB`zBj%kQ+Vfc%+ zIFT&)ihY-NVwZ;e266iMe7#3|D_DgRIe;T+f^=AopO}5Tn0>@IfGt>lod=ClD2s}S zjtVJu%jS<1nT54jh(wr%PPmiKD21Xolr?T4|b6NqeEWnlIP`$Oo8(xtcwI zo6Sg@xfzH>xG9ywDV*I%oXW|0)_I+^2%IlCoz^Lx zpZT2wFrBqYo{O2Bt2v#?d7Pj*098Pp@41_gshXgvoxS;j?x~;U>6z~-1Gm|K;yIs< ziJkSCoCM09x(S})Xqu^Mnifc#eb|-0*^LPLo;{GE4Z51zd7CD9n*$18(4~dCo;_-(^!cFb`I|l(nrKR=10V*sd846fqC-lfpz5GPngSdO znmsB5x>=m}>7c3#s<0}gZ(0Cfx~W0>p5ke$OnRMZ`kPydd|UdZm#VB%DxH-Is`45C zqr2*it?HqbI-t^-racO!(CVuxx}aLRs={igLn@>)fT}6lrYpLsvQ`m46-p}%^sGW)Nl`J?sBxo?1qyc-b(pkDuin%iSvI8ov&|0^j3$3u4v9fx*smirO>!(aBvkY6RPujT-ySiih ztHAo3ZkxQgTB&_2u|9gbcbc_=E1jk)vxN(*fm^wrd%D|us@vMF&Ks~Py135Uqpqu^ z(2J*mi>E`Ix?Fm#se8EMIjMT9x=nkt&+EQ;+rDFKw#XZ_n|iw9OShp~yE>b@84A5Q z%CH6;yWA_fy_>su3%>n3z26GJjoYdzz_91LsSGQ&W81;y3$1`V!pK|yzOAakV0*mz zdc0!`zG$nXv)i;UJHYx|vjL2~PkXm7oT_lnyYL&gFf715TmT19!Ly6R zx?09SES++zzo}cr;R~w@@W!e8n^io+e|!Lb9KHz*#lYIdZv4jupvTTz$Qe2Wvzx^| z`UKK>#&#^RZ>#{WtHX%A#SqNEew@W`Ov=vN$8HR(Lr}D3H`{={J^!l!Hvwv!JMc2oXdF1$*Ehz*Bq)( zAj`;mzOpRKw3`Bw+{o9e$Cw<>L(l`)%&@<#&nJw^mz>LzJOp>k#bSH_flSSEjL9wS z#vjeo(rL+`d(Am|&MM8%2E5X4EXhlK%N2db2u;YHjLzzO%Xx~)i(I~LOU+e0#_Eix zgv`f2oy!V<)|$-9<}A>UOw5>kx9hCQUCq_-T*2@Qs%ISk)_qLP!JO8cyvz#F$C&KW zrp(B0{Kl?J$yuz&S)9vMo!DvXqxOu@$$QQd4cH`Y&eFNckgd;HT>zf#$k%+%6z$Tk zTh0oQ%&Se*sobNh+{lA1%ndBqHap6MOw@er%(1-F-8{Q#E!uYr(5ZX?$-K#aJlpEb z&C7hcvz^;j9mc6l%E4US7G2s1&D)yo+0*ULk!{CStkGS))IA#9lAWrA{oJ{|$ad}7 z{5%A)4Bu6a&@-L3X}!v^?7F$l(|di*2;JL$jnS!m)Pwy5g#F*9Q>0Q=Z&Z?dX6_+Uc#`qE6)%ZsnXz$-Nz_gYD9&yv_Wb(Yc-00jt_p?aaBH zqb<$P1ODgNY~Th?%96~-6i(swOyNHI+p4d1t}ViGxLjcwP?dXd9-(z0u@9gKijqdV&?SiiAfUe|EP|vCS>@V)x`(4#kj^9#F)aKp; zAFbqoj_zkH>$gtj{9Wf|{n0MH?h0Sp68`MmTm|ON+tMEK%s%IbzSD|4@B}~Zx4!07 zE$d)A)a%^o_)W;GJnAl<0uQe0noaOZzQMt4=n8M`jok9Hoz^tp$3_0+N^b7MKIM}R z@Hr0R{7&MHZ1J}awltsEN*#-S3B<-hW-| zRz2oY{{(AJ^sAlirLOGntm+0n^g2%e>N0QKRlnaqpX?bg^Gkl>TCe2zUE@SA?P$;P z{QU&hp75kj*bn~fAn)SauHk{7?r4Aa6b|Rf&hsk|^gr*+fuHz|J?MVl`RUI0tDpKB zKlt&^`WZj;f^P1MfBPBV@?#G61n>8rAMdoE-nw7t6W_-YaO(l^_{0zR5kc0|Qh=iJqhY|sk0h^eK zrBH>KhO3N^k*br43bBZTjIxUVpO!XS zrlzHqx816Oz1oVhT+-C3z=Th{(3I=ihR_F(L!;3O&zMi4h@i5VMvXF+tq?Cl1IYn2 zwdj_=L<22#yLU@Lu}0@A1!E@PqbyMP66wo_Gom4T z4aX`(D0ElLO~t>J8rTp~Pr0E)m-{G1`u z`=~&E}_(6Ks4YtIrnhE;Eoz^F=M2~bI{2@%l)>9WY1Ohk!EwHRhxJ|LGjF9D4iJJbKLoJ;)Glsh!8mfVZ;<_rOn2aFsR)2 z(@-nEhzJ+TNb?V7)yyRmP1s<>YU(-rQ(~oLB(cl4H8Vvi@8J;ZYlx# z$|^*WKIv>{ibm9#s5p|lSWC>_>#K755_#{TH=0)*p4_1Vif`HW=rU$4rEFixnK3ER zt-FcaZ8psRX3{Qre;SCDxQKPEZ$6dy=H)Zv()sS2P>c2Lip6?LletR5Y1p!nX7w1x zA`^PGmj&Y-0Fy3F-RgZk&UW0Z22QOj+i(u+HlEx9^R>t0DdHlxCxYnqt&9J&NM zU2>vKZ=2<>_ogfK#&7!?oJ-k;i|nsLdkQk!M;}e7=Dxz|DU`$R?Ch?li~5W?iO-#A z#a%1l^I`{>qi^jeLfR_q_WgtU>!g?Mo!Q@MR=nwM3oP)kCiDEdrOIuL{jlA;eq+_! zA5SI88yid~qow;DqU7SAuD$$kbACPJw&zd1{U5je=1b^y2@^(GfUP%w!Lhm#-y%k{qu-fwPHJD&I=IKlXVf`sD33;_OBHSB%FTb_cU z`}lS%*17I*SyCX*9_T&+=5BK<)F8h;0tB-OQFA@?Uv0*P!UkHZb#Sv__3UE2k3?{0 zCmh!ap|nExMR0{@2tX5k)gT}w@Ly$PRuLO?#o7P?07Y!0z{Z%B2ujT^By6G!uLp)N zs*!;=0>BEvV8vl|agR=P9Ua+5LNA_3kn&?v7r(g01v(1~a2ys8a9A5Ut`LQee52_E zSwFTFQH&=#W$RE`I#gb@=#Ro2p#K4j$;n@C41Hn5Qqv}GTerUbyCx>ia6l!;s7E;n~0LVog>)&u1!3CXW(0@9c$T%m6!=|)W6 z(pk35N*u))L@2<|myN_D0Pg5MNgnf&mL#Gt0a{Hf#?g=X4B`SwIY)spQJ1l7WFaTV z#ZFqWnYuit8AT|nPX-Yb{zLZRdy>MLZ{a+Bt?%RdDgQGf<jMSLtTfl1nn;xzz$ z{Ags;O4b+U(VL+is3?b<)|Kiura`PLDx=HNU|#c}3Y{%qwOZHqPPDK{^{FhKO5WaH zbFHk~q-O<7Qu3bt4dXf zQ3KERsK)FjVI}HE4M!HSbtL5pQ+nWp3RkiNEvzp$J5jtkb-S=dWpZ!-Tw30G_re1{ zaeNcI-{vCot>`5yZN=zKCHGjp5(aLCJ*;C1s}Q0(F0p}o{NyLAx5#4jZIP9XPS*0a z$`dB7nq|4xEJJo?O73j{a?0DtikX>SMQEF)S>dT7_RQo&;zqMFr{_JhiNz?^7ekntU^aA}r9D~(PZ-$M zrY)v#ec%&|tG}}a?zaCLYkEev)`g~Yx8v(&VKchar4{g_Gil}jb-TO1>MgUUUmR^H zUmD!d7PXb%TIYW&l;E1>c8ga%T5coU)BP^Br5Vm}gHv1A%f@uYHT-X^Qv2cd*6oo; z?(Se4+ujssIKc_t)`wpjV6U3SV`ab)NH-H(KXD5BkhW{_bh}+~V05 zxQAgb^pnfH=}qrB(4n4lq(lAGR=>K|x6bvhd;RNR54+gMPWG~!{p@H@yV}>z_O`qI z?QoB~+~-dBy4(Hkc+b1u_s;je`~B~L54_+9Px!(c{_u!Tyy6$n_{KZ_@sN+aOn9scCH_!Rbd;asF554F|Px{iE{`9C%z3Nxb`qsPu{`Ihrz3gXC``X+7_PEcz z?sw1o-uwRdzz@Fghfn#`02qJ*IDiCL zfChMg2$+BhxPT1UfDZV85Ey|HIDr&cffjgy7?^b?WPUHCUoX|Ym1<6{BiZ-Wta#g$G4y~Ic z#!d3LRX+&Ma12t8dA1W$v@UD99N?(KIJTzkH7Z|Nbp4==yD}%VE)GC4u4Ut>Xmy$< zjmmaV+H6*Jtj>u*DaTvp6#eS!0!VZptvKEu_g%cXH8-^e`*I}G6t6#3piy%ci zBx`mWB_0j=zvB{su!S?YnWjhRXj-1<}i#nO;c;yK1kWVZj`Ld zcRM!WLuO5vZE0YA!&(rp%n3|t{_>o_4vj#{HjAzgk~Tw9?y^Q;R(F6>w$nVdsui2m zopx~8rXO6M?J}u4Kv^>=ZCYJ;ZP`pJF{?YR8$k0E@c;RrHbAr@f8&ui_vTLk==T7@ z4NqrR3$LTScO+(rgav`#A(yk+zp}0e?%uHvq7a7)Zh432Do)4Ditl(Q&~h@q*p{@< zGkCuj@1jbKDZQwh383|Ul0?jhYYzEr5BuHuBHb(Pt|#f$=PNAuGNOn{LOf;!Q+JDQ z!wv|J2KTR=oq%QYEB@8Dl9fR?&gqW)%kJW-h|Cg+l=Jv`J~qIoQA{~ekV)L>6CsJA z6~SY^|7#94mgHzN+rNJQ#PEop zJAcf--fH;Sfx-Ba64?M8S&9DpLQi3pyxW&-JP71p#d_3KF;PbuET0RZMK^qWJ<=6S z^WPQbUN|Vt8qz0{I%03h>WZC2MceM3Wt(F$ErZw!H`>+5hZ< z2bs!Ft}CN4p4OIxpVdCDY{J&pmb!;F0JtNRv#8I}kkGZk{X_%sIs1J>!_()(-!(K6 z?)T{$aO|m_jkwVo-BVn|MJC5}+cR-fPt;-~=gomfHr9?Il?09&t^{opt9)Qha z1X$Tz8GY>&OOJp89U!(8kw|8nlgkv;mH;j|BEE!ecwyh~$@ z?>jGr72>-^!EuVT*2#1CzI;8E^(;?Jh&uvXBc6HqWbP6@mo^3P`f%ZM`lH(#J$X&bwk!%4k*1F^2*DN{R=gqCMzTn z4vfm;UFnjvD|&iPT89Aup1T5Vi@$V$9bsSD!Om~1JHS4?aVvG;|3R2Vvp97=k_EDCDGU@3=b z1crp>|59+Hh@S8HZGA!@Nrj5!$9v_R&qyH16fV)ZFv4j`LSQ%vyM_7Kr^@mQl~G=t zUU~xe@A}uMI3hNatMcPS9E=R7xu)U6a1$0JwL*Xlr!euF`s-f)3b%dt)xm!*>)BID nb^lkvhhSk2a(o8XLr-U&N#XiPqCAMA-2#X(^zq28=mTssRuw_ACuDuaQj)jevs#+ zf)f&zl|ZrKDPFm@ALRG5_ya7SSElhuH3KZZSEhE-m^K2%D^*+ZRIgOy63RPC@m2!W zBUSrk+7Z6gPG*b=WiF9?FhS^(YdYiN9{`-81VJyI^;oRzrh?;%%2B@5LHRI7U?WhS zROXmaJ^=E^M6%v^_G7VPm?!Rvqj%GoqXLQJgONb;fXNvX$wvgzJ|=gVo7h8Vb&=@3 z@vOlFfrHHO$~EnHvV#nCk>Us0La$8Qj-zxCXl|*>Em1@MZ*Z>>|Dp7c{qYkBYS94A z&C4%1daSUh_;|^Qlc!2ck!51VPBE>#45=uqK#I?mDR!HTmo6Y_7frN^hI6%5=4+-Z z0K>#`n76QZcq|UU!QSKnJgle<%K}*44vYxH<6!{c76!u+F)??o9#Ky(=aFcz&;4*1 zHZ?__%9#EKwr769KRp9me2Mg}iWo0CG82G4Yp7P_p+jSNXF&_jie3WXYhyOq5rowx zt1Zdblm$PBk)@T%?45AJ(v`8BDt>Qso?e1`Z!{L0$Q_Oo1$EcXjZ>nCl{!1Ka`Vc9zSw|zB=OVaft zO)sc*8xFo-u^>MKRBMjStq6d^@M?o!i>-v`#@ULn;J&P`3h&*b@C!Xz&HKabX1IIf z?dI>jf1U|J$=(K)kmHn1I)w=t6h+^5lWF-1xe!6uUBO1e7K@`8tr2a9iGeqBvx((; zUGTetjW7e_?V0n3>E*f|!A~*CxrWz$C>0D(1YyhY`Da^;$YDA7!j!^HQy?KE(o{?^ zb|Q7?|O-=JwbsHE~Vk#JX}F6MrIPz>jQH8KX&J*x`QVc`L!i6TYSA@+T<@pDj*xcC!^ zmKSm~wvJqRe7egJvYvyZzzd$Hn1d=mvm2tqXCl%O%M%-+wc)APa_S-rBNd2nEBde6 z)#}w ztB+7_JTQ5EG<`d8W3)JaUqHXMW%7m~koB@BdzI%sBt z(jJ@PRNHVzKvih;7q{6C%5I~jo1Iny>lBt=v7q3bNekp_4r6xUyUbTj16$K1vqM|9 zpO}4^dhFfxq0MmJ+@sy*`ni!ke@xDe>N^0QZV)`U>SAFP zY$_DBgxGFTDhq@ofp7)6&p<>=i@5DR3uw#M{Wo?#%%^#8X5PGs+!Y}d#YaOVkl!GX zb{z4EB63l#?g%1x22&PfszC=`yqC-zpojL;L#-6nOc>ZhV)W72Q$pF4P&&aAPx2*G0+|U2(1)gMkJpUNF0iY(NN(iN7VTy z9=V%9>!Y%VS$q?YG{P1PGPpK?KQ9TlOI0=|w~q!)3ZzfK$VE_X3L-Cp5mqW-mxT{8 zxkD`ONT|phLTks7x(Jl+5bCs0KFSe}hKd&Cs$qcFPh*>jw60*voLD&}kPb3ABOH+_ zh%`WFoABg$snQ{jurYZfp~Au1 z2wP|gp_@af{j^XEk!B$>X2hUfu3D6<#yFymAWAK-CvfEGF}kU{>RfL}-auP*%!zxf0NwF!Zv0yKu|wrrFa^?kFU#*~i@-d&|> zywzFc$4QaSe;BblBKdB@ zM{n=Vfg~00ueaL@T&@!z1NRiCj^tE}8f1N6J6#@tWCS&7JnaQBTRm*(lvILc9F;J9 z`}eX0%q07>Kbri!;-hAa9*{tGWdbmbg8eZrbsba3bRWBFkhZ_WI0UU=*IKL(eqFNO zRGjg}K0Hx3RHt@L`s(3{Ofm9M@0GYCr;pMa6@6Wd%I{ak8h+BlW~a_%hJBa%>SbKz z%b(%S*8&XiM-PkPV>NpkS^}GYdp5svbaO7r%o)8jTg@lWpuSL{T%|Gs{x z12@?4*&pfbvk3dm&(8iwpv!GjARK6RpQ%-^CEiPwD` z3KZU_>f%zxh3HgbRf6&2()G9NK1!_OkS8_HfjRRERB2u-lD-4$3DXCr*xPE$kK=#T z|08V~s=t10vaPl@;$gl1&W+9bWqoCTeSPhn<85kvSsD(7!h!o$9$fF#E*D%CwB4oC z2B90dRa%4*=iNx(azyBQ_kJ3A=(;iwT!X?UGMrq5kEVI}n5<@kIstz5WC!->y>=xLipGR z-j7aBMIYFw#>Bs~X;=HR$+#weH1;{%p14+>;a=$ad~LC4wb9v8;yt_OxW-}%7cXzU zvcC8^t=O`3<*ggLo=9GRZOioy>3=T&ZOev_BtWTH`S!!(Vt4RvG!*-e7JEMA?khLM zzYUw|uYPWCm~CF|{m^!9was~_22Cl>lw!u6Z7TFMN8yA?#jsWARA2~!*^AjH^IA56 zU29JTL#p*mOpSDHBmb%l6Xgec)zd9qhHUTiI^^CYrB5CK&zSv9sK$rR#Q;mqB6(uOv zvjtbf3mDT=aXHD+>e^BfK~M4UP+@}u9~B_oerPO;n}$+0nmQ#dU=a&k3>a$4<|S4m z8D`L_9M~15`K2T+Lyy@(v1q87rHtat9Rv#8Ulm$<^#E+=nzje?OyN?gPoTu=EWYQB z$h2`s2xoA&cKLYuQC%j$0ImENnH6;0?a&{KqvDO3TY4@f0v9dLVKKT2U)^nFz>rh2 zZ`qcaZ*TKHr&v>o!yfdM9Ax!G9-pg&zqoV+zVraP=V-=_U#(B2zh2xNIRD-)=#65M z?6*{;24iQ!|R4DUyOEDyAc5Y~0a=gFX z_K2(s`69O@tsFsEsY8(Khe!q7ufop4;3uibK%li2gR0kN*1zqfQJ|FX0;aYkjUE42MosL*MHw95rV7+#_pqV@!ov zjgzOoaT{!pA=xt?zWlu5uhO619om*lUh}z&&>TH9Rz2QHz1DcK6Pn;soZUs_JBtRD zhZ(UGeaBzkFCWP|q^^vy@%i_Keyxy*n#s{`YQ8fBg2}Ps*pbZzoCjQ^O8&5DYP`qy zpI`U2eR|>J*b(%Zrp|*aXisb&K$w3p5C;wRG-R=af`^YUJl}ewDCcP&)P)9NoiH_L zEvL6(U7j(6uT^G139VSoI5Vwxd)_a^dDlyz@=SAc+-iDF^Dzwsf}m$13P8j$EYv%# z7~)h^?T(CwcsrHo$cVKzh&BZ_J(!K$)8wvAO36Q$qJw}<&Tcz^taF3T5KMb3(pQmx zxGF>OgC9iL-+1MWb#ce5wQkVOSezf_2-?1G)%>}(ADYq~k$gFi^5EQH&BElgjQw|V53Jk+5 zE=LRwgccguZ*#XQD%ZC&|KnW9Haqp#D8A6IVY}l4*&g<#jJ&> zH887!HUHNr`sRWE;zhbfCb>v3|LV8KZRK|+Nloz{*(XhQ=UFCw_rQMa0=Y70G@g| z|LjPKJ1YPBi2wbMxi==jktgxqTE?L+|NM~u=t=w02>;X$zn*F5)|l9_FaP;@+<$}V z+MxgAHj_y(|MPUEeh`v0FtAP=!AM2@&IP|kJkPa#_U)?u=2E{tG5_;ya1s`!E+@J? zF8}p)|IY#c(*ytOT>tG`|NoS}C?fyT5dYX0$)FUvA0?8|M-r_R#3JxCi~bZ|Jy01Kr8>;EbPfK`QK5>qa?_sE$zY*|NoGUM=<~HPTa|( z|IiQ7yq2?zY%!A(a0&Ih3zAphPt&ais-B}AA^8LV00000EC2ui02=@r000R807sDkl&_${g9sBgIE4>PgLD2ON}Ncs zBB?$MCisiMucOD0AVdDcRG=QcdH+(XOnKl@CKpCluEclGo=KE4Q+D9Oi%*N3DQVg~ z3G`nDZ1S9p5dc)^&7w1UDbWPVL(`g1ff_@$Ck;9WSBK71;3fr*M{3agIo62|qGEnT zsd*%ain&EjPontsY)vErk_6p?pl*Y&C%Onws$?ouh`jSkRDp%+0wZmlk^u++tPLAy zL||~U^#B9p3No6^GC}K$5?0l4U88{~$+ST~4oz|gIb|MjJyt;>H!J{va%8Z48D~jF z6hr@dr*yZA!zK`VY>coYC7u;#N8+fP)c^nh literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_close.gif b/GUI/App_Themes/Hnd/pics/button_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..84f2f747c233d2aeab63d3b030603c3d0a6d081e GIT binary patch literal 1214 zcmZ?wbhEHblxC1(_|Cxa@87>iFTa_3CjWnT@b~$QAE)A9fB5m~>+i3J!)`qMa^umL zpTGXRe*fb}esNxmQ&NIWQG$DmnAE>F`!6rBYA=sJckAQQJx@RF@%i-a_qAotH`e%+ zr}_T9lK{W`-23}n+P@E{{=Yr=?`Gw>+aH|#;y!)-b#(W-zpwWEeYxw& zrB#bJ96PjS@%A-yD%1T}OmFV3NuS)D+f$c$?(o*TSI?Yr^KL8%Uo)q@u`ue-rJR=H zsMRt`yW~|*m{`SyYHVKA`~6td-MbI>%c~X$i7lDg_Uglr6akStcONX6P`ze$dmyhs zNuv9m`sSt68@DZ+aAl$G9t(^2Tb*v#)SvSXII-08;lwE?tsK4_41RK=<=^Yw@!>j& zahCUYCBD7Bc>aW{|F3s!)Y97Jic#y zGEqSIQe^B}8Ku^;`0vMKzP`S4cYDmg_a{H^5BT?b@4i(@ZajQ@R!{$bqvZWI=Oxn` zmd^O%-WtpbUcKO8Gl#I*0_WAf%>KKSyykdpTr^crFy=*3%j(6) z`xTr&y}GC=wkCW}(5je|n^f0EZt_`l$940vv(vQWkJ+5e7H44KHZb6ru%L-yj#lZZ zH=GBSU5@pb`svQsgX#ebU3%SGca~gdoX^cSL$FziO+dwuW#<#Cs|;6_*)D{9+}Jcl z&c426!xSsyhU*I_y7edkt1u2z+ojWSKp6c3Z}5PmxvU<^|v4&baYl?(I5?zMiMWf11UQ@&Rmov!WL9ht@aXb*dZOEJ)*VAPJqI?;Clg$X1R1&GY7QON j^)Y+-WO9I65u29rgpF;w5os%*PK!~xbV!krk--`OIzIh` literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_collapse.gif b/GUI/App_Themes/Hnd/pics/button_collapse.gif new file mode 100644 index 0000000000000000000000000000000000000000..5f6f02ec1b3b439e72e24e0d03078b9541e3dee1 GIT binary patch literal 397 zcmV;80doFFNk%w1VH5xq0M!5h#VRhuCoI%qUG>wx`sB^qcyZ^Xmh;ZK>aCy9Qc%i1 zKl97D-F|k|U|jv~)^rmW%tlM#jF6uiAG#kUQVtN;Yj1rO7?>Fzh!z{sS6sgzCD?Iw z(_UiSeuB+MOvNfMK?@B)3k}auRme3uOAHTa5frQ(B4H2{(_dr5BPnJP6yJ%A;E$3< z3=X0jAdMFsj29c186ImA6-NvX-i3+EJVAjK8M+@N&rej+SzWXqBgQT?#3wDnASM6+ z00000A^8LV00000EC2ui02BZe000K6zzAzaD;kf-4(hY1aB|S7R4U?KGM>?H%k6ek zt_QBh>zU7J^erYEm(y_bx=n@$;&XSp;3&ZJb!Gtu0}TTPcV~ca3I_-P0RRXG3W{uc z0t5^_e0~fB0&GEwXp8(J{E+)$1#-S|B8*s-}IrrrzDjX{)m499^T;8oCqZRnn#8!UaX#c=)0e z)y{bb*x5TYDr*F4>upz1+n}sr!^Pw1=;F@9XV1l>Z(!o2rk!GDB_^Q|p{{LWYGI~t zv{y;vdUn2rvTA{{`WzVrTN@iYJEwkqV{;=@M|)>`dnY|T!%LB|jt(vd6xGbktv9Rd z_^jE-6=PYrjEJ zT}W8GQ_pyVl18Dm?WO31Kwg1mvPza#wq82=JLFY6jLj1j)%wI`GVC23G+W+kH8YZ5uvc7WyPV3c@+warzE&}*quPesmE}ejHqJltFKjlGhxMjgPt*SQdG7 zF|1sCykEiDuWGY`;3DVAL91d;Zc<(B+U2t-$8++t(=*hwU&T}gKRYE;FTikP<)-v= zQ<&CCY;0W2;LVue_o3yb@zUvr-VP-XADgJM2`8TMIcjPAlvk9Wg|U(`^-`l%6py1s zbZP1W%g8kcG9NGW;^fllofgZ<;5$=4g2S}%@uXLQvy{!AL>eDi_V}Q7r^d}mM>rKu zr(|C8Jg`83T~evZgzu~oFQ=iC6AQk%O7au8v5fo52&~X`X(Rf+TKs@9q36~!1Uf!u wF-IFJlL8dL;0&&;*=LMaTPp1Q@IV4r?lb literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_expand.gif b/GUI/App_Themes/Hnd/pics/button_expand.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b5d9dca11dd1887f2055a2f5dcf324c416af056 GIT binary patch literal 398 zcmV;90df9ENk%w1VH5xq0M!5h#VRhuCoI%qUG>wx`sB^qcyZ^Xmh;ZK>aCy9Qc%i1 zKl97D-F|k|U|jv~)^rmW%tlM#jF6uiAG#kUQVtN;Yj1rO7?>Fzh!z{sS6sgzCD?Iw z(_UiSeuB+MOvNfMK?@B)3k}auRme3uOAHTa5frQ(B4H2{(_dr5BPnJP6yJ%A;E$3< z3=X0jAdMFsj29c186ImA6-NvX-i3+EJVAjK8M+@N&rej+SzWXqBgQT?#3wDnASM6+ z00000A^8LV00000EC2ui02BZe000K7zzAzaD;kf-4(hY1aB|S7R4U?KGM>?H%k6ek zt_QBh>zU7J^erYEm(y_bx=oJ9=Wf6v5l<`tJ$Q8j1Po~m1OjqwZe|Jx2!H?x2MT9` zJbDQM1_KQP1_6G6m_3As1r7y0h>C%Xbv=)f0h5)Nux~w_o}dA0xoN4ZX{BkuaK?7P sbh^unG7vixI@Q+K*CsG38WI>b;Njxp79|ufCnPiL?CtF>As|5jJGdH|=>Px# literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_move.gif b/GUI/App_Themes/Hnd/pics/button_move.gif new file mode 100644 index 0000000000000000000000000000000000000000..c5de8cb6623392d9d2f3cbb0fe1fbadc7c92b40f GIT binary patch literal 709 zcmZ?wbhEHblxC1(c*el+=;gP6|Nh;0^yS>GkFP)c`1JMnjfY=;{`&L!{f`^@#sA-J z|No%s|BG3B76-J5N&Wo&_tUrE|6i{b!XUOOdf#=lTZn3M}b!y}Uj0 z|AXrPcXNBIZ02lz9Kt7X&O6}k*_0FkksFUbuRr|!$mMqj6xIK~+dOyM<6C=UY`Az% zm{=XT^lr-f2mhbXyx-OP|IONk(h6&*d0vW6`2Vn`xybzgla53I;bnWC-gx-goriC_ zq}=)=&kri7J$&)4PE_*$gYt(Hr>vDxI$>sQ&&BiqUSWB<(HS@I+cotktsExS*{+sR zGWAS8s-=I{-REj*W+cC0uei*1Ih9-GRh~S2tzuF~wGFq)shkfCTe|t=Aq6!C%7Efe z7O(+2AQBWO4DA0K0_`J`Tie<@IynuJBstYGCQh0>Woo!0pHxP0+T3~b7c9*3c8`yX z&04u?^_sOwi3!VAtlhF@{l?{6cdg#OY4`rUJF_y696h${;O0z5Ms@)X1~%rH6C3s& zW;}K)bB%A-$(5P>r_Y|hczGq4S(e!SYlkvfPqVWs`!O*KUCA=%S@qyBN5^Le1_vQl z1rHYnp+?4u5-S;&F$(bC>S46&S<|p7fstEOCTPdur9KX`n%FcvR!mxau#-)+Wy=Pk zk8_Rmgjs7I7&dlti2v@I@*}-CREkj~%V$9&i+g`-zH$CjRy}dx`@u|Cy9vtPUns$Ls&b^ K$<f8MDOUtq=tG-4t HFjxZsV%{o0 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_notdone_small.gif b/GUI/App_Themes/Hnd/pics/button_notdone_small.gif new file mode 100644 index 0000000000000000000000000000000000000000..88500067505946c438638dfb0d1add7ad92902a2 GIT binary patch literal 852 zcmZ?wbhEHbrKZjC@T76xko D0;wQg literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_print.gif b/GUI/App_Themes/Hnd/pics/button_print.gif new file mode 100644 index 0000000000000000000000000000000000000000..a8934958bed14c41f35e7e191ee04df84e884753 GIT binary patch literal 1164 zcmZ?wbhEHblxC1(_|CvEdC~TD`>vRJCNnK$ICT2@&tHGI{xf|1{NqM`@$9w7Htast zA}00g&;Ju9R`y&x9x-JTtUSEqEC2rew=!ETuE(Ii2 zpK)ueDd=1ip|FYc?ANKYrW$t_MLqknbqPEU1IK?+S9#g;ky07 zskOZecAfJMa0tnpyY}eK2XE|xvhR2GuH1Qk%YTM%KYrIwSXCz~dFjT3XCMCA24>HX zNZW5<(P3zB<(J{k!*?k%cCCr+!)Nd78>giRh~(ByT`Qwx!^IPnR_~iwl~*_Q&)R^IOznje|n{OQXN--N2)fBv35ed~5jy-$3l8xLQifN%((z}mf+_nx}x8d11V zTA`_Z!Kbf3k80_kb@#cNniwrj5o?zhk&%n>Sv1HYPgUuYmN*@xn_?tA=D0$8C*r?Ra!|k_W)q+)v zkM}D$?|L;MbIOW9CP@jC3X87dXQ%kP=7?E1um|vRq)c9=Go``1 zV;xsW$xg*KmWEXx>zDaVZn%7TYev(HnOoRABoCy9?z-@h^`f|4(V?6L2cPjSw69e- z{Z{d0X0VqVpF|hq+XXOM_c8O}Zv+?lUXm)Za zm^y!wLB^>AF3NmtT|5sIk5qcCPMdiqvoP4HbEcS>1aHKBPlkEVHJ1i#WL&WC?{6lt zgZ?YkxMy(i-(Wl`J2~B#^VqC`0Q>d_-LvW9n_LYTk)_>rf)-o8gGoC kyOzqdj7OasN`b6u^H_|SwG57FJnk`ZddMKg$jD#~02VN~{r~^~ literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_properties.gif b/GUI/App_Themes/Hnd/pics/button_properties.gif new file mode 100644 index 0000000000000000000000000000000000000000..65a13fe974d83e984982739fb91203074e46eefa GIT binary patch literal 1154 zcmZ?wbhEHblxC1(_|Cxa?f?I851ZF4>F=Jg@zbT$O($OMwX;2N`Q6!jp9&Jamv1|> z?BKcyYwx#+N!@z!ZCZEL(tXd~|NNVu==0@v`M-bvUT)KTz2Ex%$$%UA#ZN!|DoFHt z|LbpYq)kz@!>lcj`^04u1%%yAl~dOEEZcf&#<(FYI0~ zsxO_>(NY@s^m5znn))+t-uJtDADykbo}E8u$IShg-?{Vf_0HO4tS)-=$ic!`*F_tT z?~+%YwshBidDWLMA1#ztn7MfU*?XVg|N3+5<+ngyfxSD{pFDBsQe^Do$M>g8$}O1I zY|q8xTw})!dl)UD6Y*Z3Z<8AX0VqUrUc)xXIHLvFl1&ai$r+il@-`l|^ zpy({8$D(3YjJdmG%RRh?ENzNn!i)>iv9op|9H85vL6#)#^n-Y$%+L^mKPqns0g@e vJZur!b-{s0W6sBe$}(jy9=0pod%!Lqz!21`tg&pxqb?n(gRQcRj11NQ+JAva literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_rss.gif b/GUI/App_Themes/Hnd/pics/button_rss.gif new file mode 100644 index 0000000000000000000000000000000000000000..5ccd17c70361fcf3db8941bf50a3e3558a09888d GIT binary patch literal 565 zcmZ?wbhEHb)-<`TX=YdZve`3tuV2$qRW`A?{@KI(%VtcO(%Sg+!M!PM&As(C z3n%x#c=CAX+Ep)~JbwP@K~G)v^v>2VA3yXr)_wl)e$&!LlUtkCFPh&`Rla8a?B(-j zFPbu8`P|v7=gr!%ctLAf@$IXZSI(Z%*I2t?V&A+8J+GcUSu$%zOKH*6w&sP?r%Yq_8C`8ymL+i*1mP zBm<`l4>uE^D3gW}zm~GUxEGHoGrIzVn7E0mymcsxIwOag9|M;sgRq5)0F$7OshK;Q zFQX>vT>kIUa6cWU0vEaCCK_ I=D=VL0HyK8)&Kwi literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_subscribetothread.gif b/GUI/App_Themes/Hnd/pics/button_subscribetothread.gif new file mode 100644 index 0000000000000000000000000000000000000000..caefa489ed8e3f7b1a35fb99d6bc76be35a427e1 GIT binary patch literal 1296 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 M*1OLSKLi8-J8zniRR910 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/button_unsubscribefromthread.gif b/GUI/App_Themes/Hnd/pics/button_unsubscribefromthread.gif new file mode 100644 index 0000000000000000000000000000000000000000..a5aa8fec5d1b78e4bbe241689650880ae6f331d5 GIT binary patch literal 1416 zcmV;31$X*KNk%w1VH*G%0QUd@>MAMgT2akNLztMhr8za+Sz*q zIj9^V#VRk%L_vf^gHsL=!y_reB`VfxTf{*^@PT3GqJ*{{Bx5FGa1s{EJv-i0O5#F6 z-iK_frN+lGGRDNl^eDSD0JeIcf=+ty&om%9vLif_g*H1BU(&YN}r|J0{OKG|k!mZZr4 zjZM_etJzvnsbZ(cu)w-?x36!P(pFKcvCGb&ZRaX0|5zB%Xi(63VA1aL#w|0$wT!1^ zwCO-Q=~YAKIW)k=*6X&G>oYR<;JU9hGrch}!JKrsfw1U3KF;d+w0N%AaBImrK%JD6 zy`GH1p~c_d%ha; z$iJ$KqrHftcyfE6T&L%~rqWqW-dIlEIy-bObN^~O|9C&x*x~K5i_%+AtB;xd>aNU2 zOU6nh;UXg7B`MO;ytabG>o+&mW>t}BZ`sM1*<@F;PgcBBN$WyE_N8j+jDqTyf#H#q zyTG&0UQ^`Yzr>imx+Eys78ZPgkhj0NuSy~6|NpC3JMvW|OMN?Wmd&QS=@hv@vM}W86M6{P~ps`wRof4e`x<{D$Pes)n#c}4-t(Q9Jd}MNem8! z78=4KC&C~mA^8LV00000EC2ui02=@r000R80B=3}Mx-DSC{dOu*}+iBk|ZS_1I~+|KmWxO zg6|#!7Z7IX$N)q_7H@9aaA+j}$qaw~{%PH(FJI9Y5Q=zUDuI#=cnBy6tG6kGjtCH3 zWaaAh-isL?6f~Vw0g|~-Y);9L(Ci5V77*rkEoy|t4FO{sX}co{fxThCD&QE^07;Ik z|L8Jipr9EiRxoT)a|Q|vp%9Z`p~&EYg^SRO?-^n6#59NzFlvbkgNRrNDzi3Bs0{&k z-Nr}+tm5LkGa z5Y3RPbpebp0v-XpGKdIz@Q~PeM)?y~0;PyEjxOK;FakUC923U?+=#~@1OK?dLITos z!Avo8_}~Kob%^mnG&iu2)rSu1kiZ+$BUb2TflLua#1O;C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tzK& zVL(SB02>DNj{l4XI;PIdT8KxD*oGP;EE%Q1b z_;sDxtTyp2s3td)6w*)*+o>hT+slM2s?r!_nY;_mKN zIo2C|;`5ihh$#6algiAK>B0x%Bj@mntzFHYgkSXc+Sb0>A5tV&|7gy1qd)z!u}PP2*Jk@|-gjiH zm;U3mYc7{&FLmV(tWLXZbe2^ue@30=w|w*5=6eTU&$0T`cYDfBrTOb~G=J{g81bY_ zRwT7WIY6@_EIw?yn8u6pZ zFB@;MJ8_=#D{v68_xQVZ_bdL`S5?2WkEfnI?6%!-Q{J}Kb>*Aih^&&0UGQ$(+CrDi zl{05amMaHMY@1)mzJKG|*@rgme5Sx8%-883vE-BZ=O+i{X1smV8j;np#A4-=r5ak`|~j62B(VDu7$E|HPd>o1RA>h**!PY{{Kw?b7?eB literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_newposts_alt.jpg b/GUI/App_Themes/Hnd/pics/icon_newposts_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..efcfc16eea8e938dfcf2664edf908a4b67d10d90 GIT binary patch literal 871 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2ty&r zVL(SB02>D49>4C0taD;(QZ&I_Sgf#PB<zm5SQ=YTA8Dq*eX>*@CEn)6eee+CZb8u`Ej9gab3}(hzVXd7OtG?RMA^;WWMO>sQqQ8=^RN;?mkUsM@~PP^Md2p z{QFII|93pu+tFAmaDKGSo zD>PJB`)>K>rfDiux~sn0xqjMo+f~@&#K-sS%#!Rig$tyz*ZGwmSoo{{oxSp_yw>oA zyVtFrvfi^#t0eE#nmu_r_YzJ>ZEJZhwsl8J%8sd153DayIp%IP`O3Lp?%(`*PCk!l z;RtckwoabxA%A`{+k+Wz-z>dR`eKpANu{M8abMOh-TFKD_^gVbOEW(AKd`u`cKmni zPRorgElJ{=BVCTGyr1X5@`B+yy9J9#?b+|rQ@-7I+(Ro}cRN|n&%GHny_c`G bk<}q|m7=Ak*J)KX7ab!x-OJtL|8D{S_!%=I literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_newposts_legenda.jpg b/GUI/App_Themes/Hnd/pics/icon_newposts_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..646f7c60673eff9b4676056f64c22d86d001cf8e GIT binary patch literal 889 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tz)| zVL(SB02>Dht z{d;bvy%8=u6(ag&reI;@?u!h~T>{(@2NX=V6yK~c_dFRd6ku>;`h=g;6^|BedHhvX z*s}Fx!I4R)q-`Y~BoYj-|M07NP_qB|{=VA!xALJGmEWg+iaAtd(_7|sKJe>eOFwCm zYaI8t?K>TKbHP^=UemXW&UhP}EZC>`{p!x|`kn!%=FZt`jd`7Jw1`HCom`vrKJ@3U zr)##=eBFFH?_~MjW^2C6#c7ro1up0-9-ghuTH_XRWPV>|zw+s#%a6A$6|~ZRupq%P zRDa%@13j7&FaNUJ8n|EBFZ1g^!_|GO?tgwS`ebMO6N^``#pd14jw+q|O?6dZy=-mT z?A5Va8d2T1&1O!^&@_&FU>pAB-0N32*EKwk%KB!Lcd2F7e}-5IpD!iJTTk=at>*Pi zS4d1$jO?1&ysmA3^UTsKQ=i38KK4i|&3nd&j$)hUPx7w})48V_zn2UUSNOh+jp2pk z>&bHjSotsQ&&>bTetp-x{Wm|}EShj}?U|g}YggT$`{p;RR(p7c_1e`jfl*m$Y4fKS znQBUY5?^ud*SeBp)3)3-U>AeS`n}G%m-Dj~{Y7o=%;3G;_I;^Xp6tzxtfI z!Y{ucTa-6{m|G`2G0t<_*?C!aSE=8;I%S>b`R rKc4K^ksro(z4qFz{BvTy4U-&KuM)g|8D{SL#sQ7 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_newposts_locked.jpg b/GUI/App_Themes/Hnd/pics/icon_newposts_locked.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d7c455c538b678269e529954c98f1cd63e7c627b GIT binary patch literal 904 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2ty77 z12fQ#NPvZvlaYZ5RgjIHg_T2qfsvJwftisJrkIV1nT3^|gHf1MR1jz+&{-@X6%fG0 z%*Z0hDkLnz#;(MmXeh=J`2Q9I4>QncL1sY)dxkBskH0A|H?X^H{j|o}^1vnY*}WHT zO_=%mV+r^3P|3&?-z7J0B^~xYQZEozGbNXinqU7ya9Qd8Tw)w&St`M>-0574~%NO$cH! zai05P=Fc;`H|JZ5o@ChDc5z2|H1A92gmd+Y+rDUS{k+s>dF*E{-I7VtUAv>t?(2xo zymQ6o#>%XOY2HOg&i8a0?rCXJb4yC%QsXwTvFiHIp!3ze_0=Ec;1%jLvM?&DxLD>_191B%Z_gCo_0|)aLsBD;YU{j1HYJemJ04WcN4a_Tu8wE!wh| z<{fyaEqG(&t;qGqT=(SOc*i<7Fs4NNc>dM+nC0iyiu&E8aw}D(D$4Y&!mnprew@3r zG+rY^B3D>B!AIcsSx-g9*+P#zUqXvRy1iO098S2dZqvQ6?TC*vlgv^xhDUA^ NOXpcKoT>kR69Bh1HU|Iz literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_newposts_locked_alt.jpg b/GUI/App_Themes/Hnd/pics/icon_newposts_locked_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e375ae2d45688a9b18fb642655f524a246387d5a GIT binary patch literal 897 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2ty77 z12ZGgkqE%T%E8G96hskaWn<^y6kuRv1qvh7voSHVu(ES73X5=x3oFfp8tUHk~W?ezUpUbJ?{e zy>lA4Cm;X%I!#6JK0jtSeQS>6Wh_%p%rqY7Tp@w9%Aj|Gc;y zp_Qd=#$7cpvSb(-UM;#~y->*RLJSNzVIwdne$ z5Oywxq>xhONfx#Y>t%|Z&7U4rel&mL@6GiaznJkaPVKmK@bE2}=E>55)jytY(*L#7 z;-S|Sp56ZrUEZ--c2421zc;`4@Sm>PeL-#4zi^lPLf1bZk@_2LYqU*g`P1MtPE!|d zFze7=wxp-ysMv*j6D8}m3T@;$)o-db>$S(vh>5DYyWeg8T6%q_NUPTV3}$VE^8Ft5vQw!y%iq5&iwC5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tzId z12fQ#NPvZvlaYZ5RgjIHg_T2qfsvJwk%5^JrkIV1nT3^|gHc$NQygd{6C*P-3tX0o znURH6P>4-Qn4Lk9L;U|O1|Fb1lOVGogFVBh*z3RkGhB|a&z|$?n(EvKD`d{O zy;$qv^Yz8@@9V0i?`%^$my>Ilc=S-bmyVoZ(*D@>{alYuzF$@QOziijnGL79zAK!S zSM9Uy2(3(c+c7Qg=Y)5HJ_q@llEIUV%b;P#pQ&ARD}b1k=uO=TBVJhG+elg=(j z4~3g-3COl#p{T%md%w_#cP$HCb_h13(i<=Slyi{;kWpsv9O`? ziht^vBH41k(~=*hUoxA!rq!`XYwM}?nE}f=CUR^oIJ!&hMrTKY^Q2`5C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tzT@ zVL&$`0d`K1RY(F13><9i0t^hSEDWryaB*f9RyKAdzDx&{yG4KFYFbOgXGT1XX-I({Oc)Q^D#RiXM^6hSI zXLG+lzt+rX@5gHjK|MV`zVsPO964PU(0MrMlcDHpj~mO2Lj3Q{wb}in%A>aav7X`6*w4b7zVod4Y%KYo zK|8P~N5&!5#PE|mw@U1}ic1Sl%#0NYHB}SpSUG75JG=QyQ=gyO@-8!lWe&YKBPnul z+s<&6j46Ne_08_K9e5}0ezxstjXlS@#Tv5OAs0Ju2nwzd_>i_Dd&<_QJtyAI{itea za3?R>M>%idMMsWM5m&!`E*UEwLzerk>W-Tdvj0Z^vN^R!YXTMbe_Jx;3n z|E=qF?#t+jxB0iS&tJP{c57_@iH2s?IhX1dTHeuqe&oRM+((1Nq``kd5?nO$v8Cw@=X~oap_d4y< ze+Jp7AHV6{%`)tH9uYpz=F%x$GdZ3XwnoFk0G@f7t9H0NSe)@7GbZVA{r{T)jw&vU literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_newposts_sticky_alt.jpg b/GUI/App_Themes/Hnd/pics/icon_newposts_sticky_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4ead32c23db50dd3d4b379e3f4884dd92ee33b41 GIT binary patch literal 882 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tx$} z12ZGgkqE%b&cO+?3?Tw!aj>xqFfgz(GqWI6GqbR=u`@Dp2#RqE35$p_C@P5yGB5&_ zFtD&OLv=GUF|!B?u__9)u`?Jt8V43CDT{CfC5isO#lQnJiAj)Ikink8{)D>O&cj_c z54|hS%bt&WCYYF`@89e1Q`s>k+1YxzU}XMR{#3(-tG26u+^u(A;`M`X{mqvarncn0 z_FH=JZvPXBDs}O=$Q@^dX4PK$JpI)N_f66qU$@`=^lQ(*`CRk59>|v7yxZCJQ1Z{V z(m6}spS;sA$6{h&mh3TMwvnD+>BSI}sjGHu4NdjoQt4#+cW7Q&nq{+cM4+Fe`-Vr> zd`bE;xq=RKawoJqn>yR7uGdM^7o9fM zE-Ps*$D*dbsVq^G)(2%TP?}Zqmn(b!{=gsN5v3*X%8waYmYzSpTk6?UE$g+rZhw;Q z2{KDQ9-Qqp-?{NnjPKf&o9@Q&nNO}+TJZLy%=2?H7pHGDGm|b)-hKP$v73{aCO+D9 z)bH&bmxN>5a>3!1GbRfCNk62xNUV}$TX`N|bL7hGwersb{?>$5Avcx= z_2<qN>GPH~#JGkbkkAx&BQ)o4NVJz2bLoS1da8_1~p++wN)? z)Fk-}TfVq|(jxWTuMQ8RS-j!5q-P%3S9`|S!RY0SWp8XN6sGG4D1{vO-kPhs{?)8( zU%Qu4UdbOM?)dbd6T0$wrBhRo^yW~NWlQeuYT&%UxRy7ALo@H$-(#oB?lVq4p#1UJ r#=>WN4px3W8?rQa!zUFMlSVNOrz@X*Lyu}6X*=9;YiDNR{{J@tTFNXo literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_newposts_sticky_legenda.jpg b/GUI/App_Themes/Hnd/pics/icon_newposts_sticky_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..add1d7054a1d38e935d2b4433212fd9427713ecf GIT binary patch literal 892 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tx@2 z12fQ#NPvx<6J!^X2m=EL8@m7l11k$73lm&5GYcylJ0lYZra zEX*+7OpMGdfZ*fW^k$oo*dSm^t7{l_ZB zc7a)Z2?hMij+Jk-KEf3^b6#kN&P+!4H_t*;!|plsJ}lqK9?yPc0e@C&A5tDLjv zKf}}&M=A^%r(Eb){IFT+&GR{4%}S|d8mqE=R9S<(0(cbfhnzQhGMP#3M8+#gw?vON zUNf$p$|2h?*Ou;hZN@)$Tg{C;_uX&0URi!#x@wN5Hge`lxXEc?2 z+}VEW_R8$0+Eu1&xBQ(nb^YTDtJ^CDeoUUc@lMx-{TF=dPyDOR<@K%TKlZ(3-lntJ ze;4h#T^07EI!SD?@ynf)1vW4JDIk!t`BwfFb?e5O-!mpPq+Y(rd!y=uqh5$Y%gV<0 zT(_d*Z_S@o@^fjXdh<=g4>JW%ifpa8Ewm+Yx7CCdSHnK9Qdn8y;<{FBi>s@5ar#}I zcKyO9>+HI>OC8;4c}?{BxlAuzGdWHUUMAPBhLq2~p@-C2rQI2&b{swSpW**a07>>K AKL7v# literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_nonewposts.jpg b/GUI/App_Themes/Hnd/pics/icon_nonewposts.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a8d88506ed8b47bbf2991a6578a4ca6ebb0740b4 GIT binary patch literal 632 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tzgl z12ZGgkqE%X&cVgVz=S5s#K_FbCcwbR!o(ygiZFz9&13s(HR&H}Wl}S%#^=4U1c?OgUluQxmWqZI&bOTDiN1{lz*XYhe3?aKeHuKJf|Kq zCM$Fu30F9|2)57_cKG4b)u(v!YP kMse8(pOo@%IAqv=?Zv4tPba6`6nMqSvwdL=@9Y0J0YMkGV*mgE literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_nonewposts_alt.jpg b/GUI/App_Themes/Hnd/pics/icon_nonewposts_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2413d11fbefeb095999be59df4db3859b9db42f5 GIT binary patch literal 671 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tyGA z12ZGgkqE%X&cVgVz=SFa9}onG%r z-X?A_ok42-J-&I1FDsd@IJ0o&ifrDedfGeptlz)rLrZbq`h}~DCg+^_X=yRXlz~CW zrfIj<;}Rdu`;5J8txx|O}e=>jBRF%yJizQFgEPwIJlGW*7bDs6G9ZPThXyf(@oV+Px z+w8M1uHDJ{_N3~q(s8DH6A!jJthiF^bop#+Yk%r>)vX;XE7!A6ykd9s^xeCXTKg>S ZtS=7sESaY2Ch=pd)703mUsC^X0stF^#$Nyc literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_nonewposts_legenda.jpg b/GUI/App_Themes/Hnd/pics/icon_nonewposts_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e4529a2cff8b8020151c5618b7caa5d00bc5ee2c GIT binary patch literal 632 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tzgl z12ZGgkqE%X&cVe96hskaWMXDz6JTIuVPa%qhO1>|VrF4uWakhR5*A@l; z^xm$}eC11Ox+~V0UHM|#_GxOI zDTmqV<0kj;_G@0#*kcX~Ozb*7o#pI;7pFe3%eZVxm7Xf*Sd{A?WiV~Zd^4H%FYX0w z)^aM$XS+5v&j!HbISgf{h)rI!ebb9+tIxi;b~o$Wld89J$C>U;JlM*=GNjh&^4Zq*{?zNLrX4FQ k*RxN&Vs}(E)k)QJYWK$dX-DJbXLP6--EaCK_xb-#0H)@&)Bpeg literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_nonewposts_locked.jpg b/GUI/App_Themes/Hnd/pics/icon_nonewposts_locked.jpg new file mode 100644 index 0000000000000000000000000000000000000000..198b3a6652916ca095a4784ceb82e738d5ac2bf9 GIT binary patch literal 646 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tzgl z12fQ#NPvlh3v3sX5CbbSBZ~k7BP$~#12ZE`f|ZGxg^it&Lr95JRFDxEBCJg8FgZ~8 z2r3#1F|#C!I0jBU=+wme{}uxeP&1Ptvmk>#!-loYGx|>&Ck8*a653f%2mlW^*!^4g|z{--ZW$!CR@KZtf% z-ODUCb7`8G3isTqZ462kcc)FdAow9+-w~O0%Y%(G_vlPkp44``QFEnC@ZE5Mb;^6* z*u6E>7KU{Q2&hC{J5%{fFIuC5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tzId z12ZGgkqE%Z!O6u46hskaVr64t7hqsy1qw4U!xXbJF|)9-Gja$DDT#3c4P|6uWI@O> zG6^agGPAHUI3@}OvK2NO{lCS)1GJ1ukXewyp5Z#*`WM!*TAzYeu^6x~>PpE9`)S5` zZn}}r!;hUSk4sPOq`hJbCKi}bQ{%8kp?p>1`XMWn=nZeD#p<3N+ zHgoACO|_3*i)8u|9aR3Yd;6LH)nTl*G7VR-Uv+U^A4k2~R!?D*sI6Q(SN?pOWO{Fp zXN#HEd7Z4 zp*J-R>7gfkFBa9ad>380rEF=QwWIp=h1+NSJ0y4B?U>4on~neY=T_`sQmZ)HH|c9DenpVTRiRB(O#2pk-=BC2qid9TWK=ILgzRxPy`)TcCUS*Yv zl$2K?ho?P17xkvgila1E>4EoLMZRxV6~B3{4zHMSS+l5r!jp>Y7tXAn&un<)0`p3h fUo#rbXIH*t+qdo18%2vd{Dtwsnd|fR|GxC5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tyXg zVL(SB06Qla*e-+!0|PS)E1LiV&{9SQ5QYF&Hf9z^CUy=XVPz3cQ9%YqW@c6-!x#mb zm>CpV3>^y_g#r^r{@-HY0cjUx7G$tzxb}UKZC-H4tcqJz+02u7-n#cD=XhVRRhZYI z7kaO*dr6v|b)o&LqWAWlUl}gk znaBEj;XUiWQg>H8Yu>fWXU=V*$=u<8oEC4Bxf;OkRK0KEiI}{Q6=$voNxh2-?e{*k z?AA_(rDmJMa!xMwcoXYc=q&xpyh_xN=fi_<`z&uUPrM#BiD?y!!tCBHR|8J}GFp7+ zg}{sUfE_J+OARki*>QEU@-(SmTX)75v?eBI%Iuf*VYMt1J(d*F{_U-2-Cm0YKaVF% z9p8U*RidY~mraAiy>4YC_avUQ<|mdRx<^k5o{VeVzT)hYdXuWm+3PABv6(>a!WzTG0D!&7c`yUDrhsKC5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2ty9g zVL&$`0ZuMP24*Bakjc!#D!{q}^&^jj#NE+>}c& zxS&%~rW@s|_s&&avV_x#?<>#e3%eQ;Std>Sm;UTwO z@GpybWwsd`1!Hd?SKY7uS!mOG))hS}wKorXTZ;u`8L!c}xyS zxTx6}>Q-%X_`(#sui8?{{gZB9-oU+R*@M1(FP*q+Ws2p`r=646J0hm7&Z_nFU~2Ko z%UADcm6%+-Vbja9ulLMZ-;Wyof;X#gYgrZf8U}{=2zTAMW5PZ`;oA1lsD)F1<(+If SBzZ+hWYwFn!)NRN-vj`Ey1#?~ literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_nonewposts_sticky_alt.jpg b/GUI/App_Themes/Hnd/pics/icon_nonewposts_sticky_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c92fcbfa0d5f84c03bc6e52619bc4d3a6e64d0f9 GIT binary patch literal 715 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2ty&r zVL(SB04E0*BLg$47z-;KlK=xFGYcatLNzNB3mYRdJBNs%kgzDH7?&V0P*|DR5L%fS z1r3FmSy&kq9TN)|8i@ot1+o3V#lQnp!6e8m$Y9T~qiFt>IWIZ>HTS*vF?aK+Ji{61 zBadHsWYxTGd%>ljyS(i6?tad7&Y5>PS@gC-*-EWyNA-nK0j^a&uO4lfaYnZForIoN z)6$}H6Q$bT;G;1Ky&UvjI!I5W$*KTB$UClB*aOTm` zBUh8ovQ~V*l)SJ=(msPJt2WTC_nOU?#Z8U1Y-fsn3c07glF-p)^Yd&vm2SK^vgpdY z#}#js+z!P}JlJZ`aipSk{%o#Ob7pUsy|p;x-qr`7VqJer>^pno%2unAlV@7D6o%|r TbzsX=arf{F?LTV!|K9`vF*V<7 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/Hnd/pics/icon_nonewposts_sticky_legenda.jpg b/GUI/App_Themes/Hnd/pics/icon_nonewposts_sticky_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e9a6ad90971a46974f89d6f0db0b07d0a9b3116 GIT binary patch literal 670 zcmex=C5UDGKfoZ!!63jOz|1Jfz$D1XEXer(2tyvo zVL(SB04E0*$S#Bckj2W(A^;|t5#mhDEUavd>>Pr^BAh~^Vq8E&fevG4W`*fw6l7v% zU@>$IOjO(`{7^{AXwm;$3_L&+m;{*x8SEMMu6v%f{S)&qi3tg>?V|3gn(bYF<>N=) z)BGPVyf(5c6WDh5@%BwibI*AvrP03idwra&ngGEBu!~}nqr+(V; zSmIi5c&^(_ublmk0z1^d<^TNnT$bZqhOWbx>)w;@%H{X$+HH7TxRG1 zzgcPi;#BF4w~LR2mgmcg{@H)Vt80(gGJ}cVvso9HsXm`_^^1^n*TGlM6+&jnblj~} z@^x%>S;iV_8d|Cx5~`{BH%>5Qx!Z#qg1;L+?dQsq3FlPAS|V$PZsE-Q^T X*B$#iTeQYrqC>^#KI=Ex;{P`R57f#x literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/main.css b/GUI/App_Themes/LLBLGenPro/main.css new file mode 100644 index 0000000..350e837 --- /dev/null +++ b/GUI/App_Themes/LLBLGenPro/main.css @@ -0,0 +1,554 @@ +/**********************************************/ +/* */ +/* HTML Tag styles */ +/* */ +/**********************************************/ + +A +{ + color : #1f87aa; + text-decoration : underline; +} + +A:visited +{ + color : #1f87aa; +} + +A:active +{ + color : #FBE39C; + background : #006486; +} + +A:hover +{ + color : #1f87aa; + background : #FBE39C; + text-decoration : none; +} + +BODY +{ + font-size: 9pt; + color: #000000; + font-family: verdana, arial, helvetica, sans-serif; + background-color: #f2f1ee; + background-image: url("pics/background_page.gif"); + background-position: left top; + background-repeat: repeat-x; + background-attachment: fixed; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; +} + +CODE, PRE +{ + font-family: Verdana , 'Lucida Console' , 'Courier New' , sans-serif; +} + +HR +{ + border-top: #1f87aa 1px solid; +} + +IMG +{ + border-style:solid; + border-color:#1f87aa; +} + +SELECT +{ + font-size: 9pt; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + +TD +{ + font-size: 9pt; + color: #000000; + font-family: verdana, arial, helvetica, sans-serif; +} + +TEXTAREA +{ + border-right: #1f87aa 1px solid; + border-top: #1f87aa 1px solid; + font: 9pt Verdana, Arial, Helvetica, sans-serif; + border-left: #1f87aa 1px solid; + color: #000000; + border-bottom: #1f87aa 1px solid; +} + +/***************************************************************************************/ + +/************************************************/ +/* */ +/* CSS Classes, used in the pages */ +/* */ +/************************************************/ + +/************************/ +/* Tag specific classes */ +/************************/ + +/* Class for links which shouldn't have any decoration. */ +A.LinkNoUnderline +{ + text-decoration: none; +} + +/* Class which is used with Thread subjects which are a link. */ +A.ThreadSubjectLink +{ + font-weight:bold; +} + +/**********************/ +/* Base color classes */ +/**********************/ + +/* Class to be used in tabular lists to get a slighter lighter background in the row. */ +.LightBackground +{ + background-color: #faf9f6; +} + +/* Class to be used in tabular lists to get a slighter darker background in the row. */ +.DarkBackground +{ + background-color: #ebeae8; +} + +/* Class to be used in tabular lists to get the normal background color as set in the body in the row. */ +.NormalBackground +{ + background-color: #f2f1ee; +} + + +/**************************************************/ +/* Tabular data and form oriented classes classes */ +/**************************************************/ + +/* Class for an empty row in a tabular list of data to keep the lines in the table */ +.EmptyRow +{ + border-top: #1f87aa 1px solid; + border-bottom: #1f87aa 1px solid; +} + +/* Class for an empty row in a tabular list of data to keep the lines in the table, however this class has only the top border defined */ +.EmptyRowOnlyTopBorder +{ + border-top: #1f87aa 1px solid; +} + +/* As EmptyRow, but now at the bottom of a tabular list of data */ +.EmptyRowBottom +{ + border-top: #1f87aa 1px solid; +} + +/* Class used for a table definition which are used as the explanation boxes on pages. */ +.ExplanationBox +{ + border: solid 1px; + border-top-color: #e1DdD2; + border-left-color: #e1ddd2; + border-right-color: #DdD9Cd; + border-bottom-color: #DdD9Cd; + background-image: url("pics/background_explanationbox.gif"); + background-position: left top; + background-repeat: repeat-x; + background-color: #ebeae8; +} + +/* CLass for the normal form buttons, used everywhere in the application. */ +.FormButtons +{ + font-size: 9pt; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + + +/* Class for flat form buttons used in the message editor, for example the [b] [i] etc. buttons */ +.FormButtonsFlat_Light +{ + font-size: 9pt; + color: #333333; + background-color: #fcfcfc; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; +} + +/* Class which is used a fill in form window, which is placed inside FormContent */ +.FormWindow +{ + background-image: url("pics/background_explanationbox.gif"); + background-position: left top; + background-repeat: repeat-x; + background-color: #ebeae8; +} + +/* Class which is used for a general small border table with borders around every cell. This class is used + * in the IP Ban list and in the MessageEditor control where it's used above the smiley list for the caption. */ +.GeneralSmallBorderTable +{ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #333333; + background-color: #fcfcfc; + border: #ccdee4; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; +} + +/* Class used for a table definition which are used as the legend boxes on pages. */ +.LegendBox +{ + border: solid 1px; + border-top-color: #fcfbf8; + border-left-color: #fcfbf8; + border-right-color: #d7d6d4; + border-bottom-color: #d7d6d4; + background-color: #f2f1ee; +} + +/* Class used for the message header, which is the header right above the message text containing post date and ip number. */ +.MessageHeader +{ + font-size:8pt; + border-bottom: #ccdee4 1px solid; + color: #787878; +} + +/* Class used for the message footer, which is the footer right below the message text containing signature of the poster and the 'top' link. */ +.MessageFooter +{ + font-size:7pt; + border-top: #ccdee4 1px solid; + color: #787878; +} + +/* Class for the slightly bigger text in the description text of the author of the message next to a message */ +.SmallFontAuthorSmaller +{ + font-size:7pt; + color: #024961; +} + +/* Class for the smallest text in the description text of the author of the message next to a message */ +.SmallFontAuthorSmallest +{ + font-size:6pt; + color: #024961; +} + +/* Class for slightly bigger fonts than SmallFontSmallest */ +.SmallFontSmaller +{ + font-size:8pt; +} + +/* Class for very small fonts, used everywhere in the application */ +.SmallFontSmallest +{ + font-size:7pt; +} + +/* Class for the small font used in threadlists */ +.SmallFontThreadList +{ + font-size:7pt; + color: #777777; +} + +/* Class for the area in which support information is placed above messages in message view */ +.SupportArea +{ + background-color: #faf9f6; +} + +/* Class which is used for the headers in the support area sections: Support Queue management and Memos */ +.SupportAreaHeader +{ + color: #000000; + background-color: #1f87aa; + background-image: url("pics/background_supportarea_1line.gif"); + background-position:top center; + background-repeat: repeat-x; + + font-weight: bold; + font-size: 8pt; +} + +/* Class for a row in the support area in which support information is placed above messages in message view */ +.SupportAreaRow +{ + border-bottom: solid 0px #ccdee4; + border-top: solid 0px #ccdee4; + border-left: solid 0px #ccdee4; + border-right: solid 1px #ccdee4; +} + +/* Class which is used for the column headers in tabular data in tables. */ +.TableColumnHeader, .FormColumnHeader +{ + font-weight: bold; + font-size: 8pt; + border-right: #ccdee4 1px solid; + background-color: #87b9ca; + color: #024961; +} + +/* Class which is used for the description displayed below a TableName or FormName. Only used in TwoLine table / form headers. */ +.TableDescription, .FormDescription +{ + font-size: 7pt; + font-weight: normal; + margin-left: 10px; + padding-top: 0px; +} + +/* Class which is used for the table header for tabular data with a 2-line header or a form header with two lines, used everywhere in the application. */ +.TableHeaderTwoLine, .FormHeaderTwoLine +{ + color: #fbe39c; + background-color: #1f87aa; + background-image: url("pics/background_tablehd_2line.jpg"); + background-position:top center; + background-repeat: repeat-x; +} + +/* Class which is used for the table header for tabular data with a 1-line header or a form header with one line, used everywhere in the application. + * One line headers don't have a description. */ +.TableHeaderOneLine, .FormHeaderOneLine +{ + color: #fbe39c; + background-color: #1f87aa; + background-image: url("pics/background_tablehd_1line.jpg"); + background-position:top center; + background-repeat: repeat-x; +} + +/* Class which is used for the name displayed in a table header of form header */ +.TableName, .FormName +{ + font-weight: bold; + font-size: 11pt; + margin-left: 4px; + padding-bottom: 0px; +} + +/* Class which is used for a row in tabular data. */ +.TableRow +{ + font-size:9pt; + border-right: #ccdee4 1px solid; + color: #000000; +} + +/* Class which is used for a row in tabular data which is selected, like in a gridview. */ +.TableRowSelected +{ + font-size:9pt; + border-right: #ccdee4 1px solid; + background-color: #fbe39c; + color: #000000; +} + +/* Class which is used for the sub name of a table or form. This subname is displayed below the name in a slighter smaller font. Example usage: thread subject + * in messages view (Messages.aspx) */ +.TableSubName, .FormSubName +{ + font-size: 10pt; + font-weight: normal; + margin-left: 10px; + padding-top: 0px; +} + +/* Class which is used for the container in which a form or table content is placed. */ +.TableContent, .FormContent +{ + background-color: #1f87aa; +} + + +/* Class used for a TD definition which is used as the welcome box on the startpage */ +.WelcomeBox +{ + font-size:8pt; +} + + +/****************************/ +/* Header related classes */ +/****************************/ + +.HeaderTop +{ + background-image: url("pics/background_header_top.jpg"); + background-position: top left; + background-repeat: repeat-x; + background-color: #1f87aa; +} + +.HeaderBottom +{ + background-image: url("pics/background_header_bottom.jpg"); + background-position: top left; + background-repeat: repeat-x; + background-color: #1f87aa; +} + +.HeaderLinkTop +{ + color : #fbe39c; + background: Transparent; + text-decoration : none; + font-weight:bold; +} + +.HeaderLinkTop:visited +{ + color : #fbe39c; + background: Transparent; +} + +.HeaderLinkTop:active +{ + color : #fbe39c; + background: Transparent; +} + +.HeaderLinkTop:hover +{ + color : #fbe39c; + background: Transparent; + text-decoration : underline; +} + +.HeaderLinkBottom +{ + color : #fbe39c; + background: Transparent; + text-decoration : none; +} + +.HeaderLinkBottom:visited +{ + color : #fbe39c; + background: Transparent; +} + +.HeaderLinkBottom:active +{ + color : #fbe39c; + background: Transparent; +} + +.HeaderLinkBottom:hover +{ + color : #fbe39c; + background: Transparent; + text-decoration : underline; +} + +.HeaderSeparator +{ + color: #0F6C8B; +} + + + +/***************************************************************************************/ + +/*******************************************************/ +/* */ +/* CSS Classes, used in messages HTML */ +/* */ +/*******************************************************/ + +/* Class for text defined with the [size] UBB tag and size value 1 */ +.MessageFontSize_1 +{ + font-size:6pt; +} + +/* Class for text defined with the [size] UBB tag and size value 2 */ +.MessageFontSize_2 +{ + font-size:7pt; +} + +/* Class for text defined with the [size] UBB tag and size value 3 */ +.MessageFontSize_3 +{ + font-size:9pt; +} + +/* Class for text defined with the [size] UBB tag and size value 4 */ +.MessageFontSize_4 +{ + font-size:12pt; +} + +/* Class for text defined with the [size] UBB tag and size value 5 */ +.MessageFontSize_5 +{ + font-size:14pt; +} + +/* Class for text defined with the [size] UBB tag and size value 6 */ +.MessageFontSize_6 +{ + font-size:18pt; +} + + +/* Class for text defined with the [code] UBB tag. Text surrounded by [code] UBB tags is placed inside a table. + This class is used on the TD of the table which contains the actual text */ +.CodeText +{ + border-right: #ccdee4 1px solid; + border-top: #ccdee4 1px solid; + font-size: 7pt; + border-left: #ccdee4 1px solid; + color: #000066; + border-bottom: #ccdee4 1px solid; + background-color: #fcfcfc; +} + +/* Class for text defined with the [quote] UBB tag. Text surrounded by [quote] UBB tags is placed inside a table. + This class is used on the TD of the table which contains the actual text */ +.QuoteText +{ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #333333; + background-color: #fcfcfc; + border: #ccdee4; + border-style: solid; + border-left-width: 1px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; +} + +/* Class for text defined with the [offtopic] UBB tag. Text surrounded by [offtopic] UBB tags is placed inside a span which uses this class. */ +.OfftopicText +{ + font-size: 7pt; + color: #777777; +} + +/***************************************************************************************/ diff --git a/GUI/App_Themes/LLBLGenPro/main.skin b/GUI/App_Themes/LLBLGenPro/main.skin new file mode 100644 index 0000000..a903f6e --- /dev/null +++ b/GUI/App_Themes/LLBLGenPro/main.skin @@ -0,0 +1,113 @@ +<%-- + + Main skin for the LLBLGen Pro theme. + + --%> + +<%-- The logo image as shown in the header of every page --%> + + +<%-- The link URL of the anchor in which the logo image is placed on every page --%> + + +<%-- The imagebutton used to mark a thread done and which is shown when a thread isn't done in message view --%> + + +<%-- The imagebutton used to mark a thread not done and which is shown when a thread is done in message view --%> + + +<%-- The imagebutton used to subscribe to notifications for the current thread in message view--%> + + +<%-- The imagebutton used to unsubscribe from notifications for the current thread in message view--%> + + +<%-- The imagebutton used to bookmark the current thread in message view--%> + + +<%-- The imagebutton used to unbookmark the current thread in message view--%> + + +<%-- The image used for the print button in message view to print the whole thread --%> + + +<%-- The image used for the move thread button in message view to move a thread --%> + + +<%-- The image used for the delete thread button in message view to delete a thread --%> + + +<%-- The image used for the close thread button in message view to close a thread --%> + + +<%-- The image used for the thread properties button in message view to view the properties of a thread --%> + + +<%-- The RSS button used in forum/thread views --%> + + +<%-- Image used in thread view to show that a sticky thread has new posts --%> + + +<%-- Image used in thread view to show that a sticky thread has no new posts --%> + + +<%-- Image used in thread view to show that a normal thread has new posts --%> + + +<%-- Image used in thread view to show that a normal thread has no new posts --%> + + +<%-- Image used in thread view to show that a closed thread has new posts --%> + + +<%-- Image used in thread view to show that a closed thread has no new posts --%> + + +<%-- Image used in thread view to show that a sticky thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a sticky thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a normal thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a normal thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a closed thread has new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread view to show that a closed thread has no new posts. Used on alternate items in the repeater --%> + + +<%-- Image used in thread lists to show that a thread is marked done --%> + + +<%-- Image used in thread lists to show that a thread isn't yet marked done --%> + + +<%-- Legend variant of imgIconNoNewPosts --%> + + +<%-- Legend variant of imgIconNewPosts --%> + + +<%-- Legend variant of imgIconNoNewPostsClosed --%> + + +<%-- Legend variant of imgIconNewPostsClosed --%> + + +<%-- Legend variant of imgIconNoNewPostsSticky --%> + + +<%-- Legend variant of imgIconNewPostsSticky --%> + + +<%-- Image used for the Expand section button of the front page --%> + + +<%-- Image used for the Collapse section button of the front page --%> + diff --git a/GUI/App_Themes/LLBLGenPro/pics/LLBLGenProLogo.jpg b/GUI/App_Themes/LLBLGenPro/pics/LLBLGenProLogo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6f0e9e6345205d34cf51a64965698e73c22660bc GIT binary patch literal 28864 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 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/background_page.gif b/GUI/App_Themes/LLBLGenPro/pics/background_page.gif new file mode 100644 index 0000000000000000000000000000000000000000..2b0709c5787d65e0475b96c4d7b6ec719b6b34c7 GIT binary patch literal 18320 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 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/background_supportarea_1line.gif b/GUI/App_Themes/LLBLGenPro/pics/background_supportarea_1line.gif new file mode 100644 index 0000000000000000000000000000000000000000..4555daafa6b80622697108d426a12aec33dbc7c4 GIT binary patch literal 1358 zcmb`E`A^da7{k0->ca-GR+!luXp3=m-$;mZ>q6qJkpp z>ZXQ@so;SQ0gan7kCYZR#Ur}8;iR&P458oqZkuha?r+%p!}H7YzE3_+-uIUkYTqj@ z0OY_p00aX}z)wTqBm#phL&A{H&r%Fcpa?|ZC_|GpMbH#Z5*UhrI0j=VgrP7+VkCj$ z7((C(%TO>hNni-*o1h4c#8JpM2|<%IiQ_op_tOM{QY222SkTW<6dv$1EK3FbGy?e` za02p8z_1TT;Q&kf{gj_2Lt6osLSP?;K!E^*q7WXUfqXPgfFVu<1i^`5fTl?dhCmF1 z8HNZ1LKS?VZxTge6owcoln44*It0zq1Wn@r}J5E$ys&{XKm&yXxlQ3MM7uag)E`!6s3jlTH_Ae^cN>MZpK z4jyV~Jbc8W$x-GcD*;ZkExC@vQK^z`cD+Wa;Q+@t%F{M|j;1cBMGxcvCtEd|*49qd z*S)H(PVx+Qy;$}s<^gPaZukFGi%|P{s|D3F)lxC zig(u)h~7@w)1<@u`)%sNmLodH`H$_f>7LGu+h0FAt&J!S|MXbXa_)+nx!_itIJ0dzdt04T0dX)^3}Bp>8%f|w!ScEEWf(V?!q-~^;Mn$dmNj1rhZ$*oWcdF z_R@Mm=8Od&l{<8L3-mm}T5THH_XYi2b4pyj_9hb{bM3v?z5mW`W(;4oE<7<=-4~Wv zWzFM8Zq8F!rmJd9T>fTBqD4^D&&sUO-3E} z-IdOy_!tw`CyX�fF4;*w8G0TK>wKGuTl!Wh;nGE&DRp=Re!DWWTjmwg@=0Q6$cm zl!eXnNH(1m8y=sN6(9fo&uQWkX`fxZB>>pPfb_zNRYu3gQymjP)1-NMytakfNDj9_52Ut9)t?#8ev>;`9<$tFG{h8SqJFm*I<$vy!;^Piu>B#qMP|$ zx5gJcqj>cRNc3p)Y6KWNI6Tlh`lyF@f7=fTt9o3b%)i{?)a>khd4ArLK0bFxEiXDwt`3Wy zb;@G~($`4___Ly(Y#U5*@8d)puX%Kwl+1LeB;}9JtZ07N(e3y6o(B|P8>aw-+zy5F zx033kJBLiWALc(R`+Uv9p>^$-HA9tTk1O&m3BF6P19b9)Xu2Wu1D_$fkom&H(M8pZNs-~6u^>y0U>Oug8%>k literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/background_tablehd_1line.jpg b/GUI/App_Themes/LLBLGenPro/pics/background_tablehd_1line.jpg new file mode 100644 index 0000000000000000000000000000000000000000..48e8a5f8f7d7a0f8e0e2c5681482e963e4cad034 GIT binary patch literal 346 zcmaKnF-ikb5QhJmd2jbYLf8=$tZcl1&1FL X{n>w@+4uN)b$xu-|C)pnd-3HLNnb7X literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/background_tablehd_2line.jpg b/GUI/App_Themes/LLBLGenPro/pics/background_tablehd_2line.jpg new file mode 100644 index 0000000000000000000000000000000000000000..18963d8724da1fdabbe08396d9d802237514da73 GIT binary patch literal 471 zcmex=&7Rf?MV532u|eH@H;_jLYs$ z<&Ha~yS+a#=%x(o_7vBxshUBzH)&?y@QN-IowF%id(z1m)~@vz#IzphgwIdVspisu wvAU`Im)CqJ-Trx%%+sgLVGAmd^gNKN&Nyj@xTb}$rUlQE2S$@y>i^#a0Nj3GnE(I) literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_bookmark.gif b/GUI/App_Themes/LLBLGenPro/pics/button_bookmark.gif new file mode 100644 index 0000000000000000000000000000000000000000..3651d20df6c4ffd354b42bfb3e82db05f074c3e6 GIT binary patch literal 1262 zcmV=5Ald?vEg#Xqb|IGy)c$Y|tk`P5!4LV2)D>e%; zJ|Ksx6zC9!^^aX z?8!0z-7^3FlgptMDvPRHnyAdNd>@6Un|wR}|CaybRIZX&|IZ3AjHqj`$2fzRgML7# zgdD)7GQXQQ9e<#%i%md!hRd*R)3r1I@LJk<6M=NbK0p6 zet}^B_>L4;Zc2lMDTk#0+AS`Gm;dZYBZ#U0=t=w02O=SAgOJ44VPHYZ zqa^?HboKDSLuX~Emuvmb1+bcEJa~k`s&`g}cPWFO_U)>~t%XIKxJh(%|MP4@i=cLI zMm&H`C(UnqWt-+OpcrX(-HseQ!Rm-{^DZ)=PPP%OjDDe z(Y%&td{*(}s`>A!|K2$I$^hWE5`}Fsf_XRU)MEMHQQXO+`S!_9ke&b37y909ONoxy zu_Kb7hX3+o>$?Fpbb|2Xp8V{cNQai#!;jXe2U3fS+^+zqqJcYmigk%_|NDsl{g1$> zcsziK5>8^7iYxutD2#h(*-(xf;@hJ`sRVfu6LN4ck#v!S%rQogq`;7 zuK)C0!>oWyjFSxUg_GPEq|Avej1y99Y>tGWURy;fT0dPPAQD87GisLw#zDwt_(9k6LI*%LkgADQVg~ z3G|->5qm({nFCbl&7#jICyBrSI$~fQ>#{B$ znLGb_r_9Doo}wy!P;}5E#KS8LU^1!8l&wYaXn_ZaDM{nYI~lm}#&|TUG{`eg5J84ar}VM~ zG42p4VM00qp#&zyADY3H3% Y9H0O=s35S1^@s6 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_close.gif b/GUI/App_Themes/LLBLGenPro/pics/button_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..b06226595ef5c6a944a7bc3f92544031111cd7f0 GIT binary patch literal 1214 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 XCPLi1_n2z4+UlJ+dFu3OMFwjC(&T04 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_done_small.gif b/GUI/App_Themes/LLBLGenPro/pics/button_done_small.gif new file mode 100644 index 0000000000000000000000000000000000000000..fe53614d6ea8115bddaa657e4eb0a41ef0d4f80c GIT binary patch literal 872 zcmZ?wbhEHbaTPp1Q@IV4r?lb literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_expand.gif b/GUI/App_Themes/LLBLGenPro/pics/button_expand.gif new file mode 100644 index 0000000000000000000000000000000000000000..566e53f014c3832a0527624506457bc99d7a905b GIT binary patch literal 624 zcmZ?wbhEHb6k!lyc*ek>)UopY^@8eE6Mo&!)$d(qKY8J_t(|+1)Twl?ynnHD@vgQ@ zXDa^O$?aI*o4I(}uEX_O-OI0@t(d%}D`fWU3#ThRr_W1VFyr}^;tl(ocr8784qooq zf2sfQmBP&@>vo;XUVmIHv0A`AQqVJ6s<2PKb$RTHLz+G7{1@&CTe@E?sai6>TR1RH zx?+0V%0mJ!q3&~ba_Lw|WVI@Ht`-T;y*#uUtU|?c&U$V2H&=H`scm)@S0RaFlSl9D@4PSyzA#30zz(j{e|bZU-eaa#wEX3T{T R2RASGpKqD)f`f&@8UWLl$rAto literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_move.gif b/GUI/App_Themes/LLBLGenPro/pics/button_move.gif new file mode 100644 index 0000000000000000000000000000000000000000..e7d97c9a2dc928f63f7e062ecac79d5ed6e040ef GIT binary patch literal 707 zcmZ?wbhEHblxC1(c*el+=;gP6|Nh;0^yS>GkDtE&e*NLcjfY=;{`&L!{g3|-sy==D z{r|dp70&gYy5+XL1|b$y7`i@=JR7;@kQo&tHA`VLWM5#Iggo_Qu?J`1#Y6^5XUX-_5%=}fDVWR#R&uZ|AsIviR9L{_Kr?|d0#7jvy6$8CQq3vE5~P>5t1@@-uwj%v&4hr zViU7gu3EijZG2L~vK4E$Y+1i?`PN;lw{P0LfA7w$%p*sS?K-$QlaY~~i-UoUIp)NM zeTNy3-OAi{?NFw`>9glAUS27vkR_URa%CpVX?7M9BPM2^D_I`gtKJ@FeNZIA(4fpT zO+hHYBVt2~t5$s`!=7fhl!k6mpC}a%234te`MHwIQYVI7H^6BOrj#yMvf&GahGGLP9@clFcqudlYQ zTeqmGwW~BI!a&`t#p3X`wYRqyC~UX55X9WZZ(Q;D)!ozAPfpa5NqVEf8MDOUtq=tG-4t HFjxZs?4&5* literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_notdone_small.gif b/GUI/App_Themes/LLBLGenPro/pics/button_notdone_small.gif new file mode 100644 index 0000000000000000000000000000000000000000..88500067505946c438638dfb0d1add7ad92902a2 GIT binary patch literal 852 zcmZ?wbhEHbrKZjC@T76xko D0;wQg literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_print.gif b/GUI/App_Themes/LLBLGenPro/pics/button_print.gif new file mode 100644 index 0000000000000000000000000000000000000000..7c4eba1910d81a900594e156c2fadb5997e9c14b GIT binary patch literal 1164 zcmZ?wbhEHblxC1(_|CvEdC~TD`>vRJCNnK$`1$M4q0`s7{xf|1{KGG)X2b4NqA|s@ z*B;B;c;eTe|6E$8-fd2IqNp0(_n*IM<^5~-UXILezI5Y3&+Ls4pMRXY_UN4#e{Veg>Jm{T z5}tSB_V;HW{xwcqS<=4FG+VZQ!NX_ok6wKj*tK-ZqOIQXmD%f$o3t%|{qB=Tbjkgv@9O)P zR&~vf%4xm%;7!Z4bxRMu_e`oWESoA*G5yi=H;Xr&l*nv7cK*T4m4~c4R;=B5YQ^Sb z0ZG*reJiBPr}0|4bLp6W`tqZC$Jy$s>wOcetGgCT74&}k`ZKR?>VzX#uikmFaPyhf z+fNAjC3(eF_$F2*6?Z#^=Jzhx6_{MR{m`Yy&t5BbtmZbflW$#a8<<@`VU^|7EqhPh z6i=#|Fn>$^u5<2lcBZU3BHOT#&(2S?XPsD5b=kJlTD|Ldj2%Q{OJ(cl2Q1wC|Nnpa z_Eiic4=Da*0ee~pM1t}J1IK>`(Vr3}s}>w=<`6dW5M&c+=3ArWHOFJ)qHY1Ma~mEt zty+A%U%`3TE@$VE6+!EQR>hp$^i(5wiO-@O&&khD&rr{P6;m0kcGg>fi9=Q@fx~}> zU3AvL%d0ZAnUbVd3M|}|?l(<2%EdEyfdiABMA`|M6>4zS!~ES-)xyOdDWSX z3Ep$pacYGgXgt8tu*zfoGM0@CE??eibnn26Lu{Uk2U0^{DIU@2pUdrkz+-{Sp|k3| z{R*e&s+`EYtYFW#rz6pWL*-)A!wo-}miY9Wbt<{OSlq@mQFz1IyiF;)L>DQu@$lSe zaB?V^TGwTgace=#Bty0=o(%>^E4@~yoxGE|A@PvsBsHr?JQ4M-2l}3CS~`4WSg`N! zZzj6~{+(*fOvaHqik)gF=Jg@zbT$1DD@zI`Qi4y-x*+-uAsqUhlUq zNc8%0yF72>iTA($zTBocVeS2C-BtOCKB6(j%MPx4|MTzDPrq)x`1bx}!18TpmhOA@ z@87?tm)mAds4I$gsNQjQ!ko>2{{Bl`?wzv6XWqKQifv0yo;WmT=?<@XyJjrfCRNaT z^vJlFK0{e{Y^#@%MNrdzpLgKI%mhsWm`|} z-LZbz*3<5$%J&W??!WwQbBC08QVp-A`>e~8>vx^wwel>Ev~e!6EsS+F)f9jA>WN&_ zV&h4hZoc>yz5L*`rMsps-Z^W_qn9rqWv@T}?9(p+mr%>8TPhC3&RKQf*2{12fBl(o zXs1+`F7@}P)5UY9uAH!hs2Jc8FrCYUj-Dj z*jV|$#q8`VPHW?_`oO`_pwJ-56u5+|c^EA(r?7O_iSub!isEHkUk@zgY%evWUc?|P{(rk9^domgcR;ip< zr+DmO3pnT`Y{trSC2ePknixaYg%F0q^oC;I!<9*?TF8zX z+f@YIG#<8y2pKsF`s@&NQIRQo@vvRt+yhogtsX@d6^&&p9(C#bQgjw)WMr@g01N_( A00000 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_rss.gif b/GUI/App_Themes/LLBLGenPro/pics/button_rss.gif new file mode 100644 index 0000000000000000000000000000000000000000..c49fae6d89ce5e81bede627f7c3d6c037115dd66 GIT binary patch literal 560 zcmZ?wbhEHbx-L-*c`0|NQ(P3>XF)DE?$&WMBwk&;dCF6ekSqy$vBuj%+M~ z{0zd998GHS+CridK7Rgz>~0Rh!Jay-Qvnv&^hDXTGcwPXIX!Hp(aJ$S|zG-Y2J){Pypqr6 zUL^1$;_{_#b@nZ(a=0SM6{f>h9$Td%;A#SZ*PxoGwOA$blGXW*u3^!4t8xI)0q`cM zOi^BrpX*gAU_P++I&b-c7s~5;3{W=uWDXz+sFhAG!bYNMdQc|notlp{Vd`-kc-E|& z0#Ba5f?-T+0k6hH6C9?r23IQ$0O6Tl+4w@dw@3%x>nbX=&RZhD{DTqkux$>2`MUrN zf_Y0H9R(__jk)XP#@$jM^P zZV}#vjl;J_`}>V$42eQ927n3U5$G}0moEi>iA^6StbI=YA>>^w@KRA#H)0^hQ6?S0 z9E?u2(jjiQMxK{xMDN{l|Z<0l|T0M(v8Zii4IFR$b#4$+@0^!7^f4z9)r+u17$?C%Rmb}p1P ze1Y@UNCy{3?``t={pq)>pl=uH$4OdUv2O%z&TP{z5>U40>745WDdAbRGWSs2k0i2N z%Oqm3$M(6hgwd|VA3Rdy7i3p}PkaKB`2kzqJP)b#jGsa0yLH~5uJ`brQEq3Ds#N94P zSh31&ElSa3qVaC)uI#cqmB-w8VBLyakeGBublfuz@p2yw?9`}lAuMep) zzZ2LngS6a4xURnY);%(}{_szOv|+I=W=R@vX94vFBSxGpFyW#NsT`_{!yR)RDcE>S zyO^B8I(XS9hkRrpq$c!;Q-H~6rw`VNmqm-FKg|?+??=jF-RqG!(x#&_Na(o3F;|xD zbn?#NhIEF);9DZ2+L80wepuxgX{?gG!;#u3{;_iU`^1y++^4l^m5qCsim)|i7FG1Lif@hsii@j^`|9(k+O^oef}?tq?u>{ literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/button_unbookmark.gif b/GUI/App_Themes/LLBLGenPro/pics/button_unbookmark.gif new file mode 100644 index 0000000000000000000000000000000000000000..83f3819168ef77e1f51ed05dc678453098ee3e3d GIT binary patch literal 1279 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 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_newposts_locked.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_newposts_locked.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cfa28684594ee3d258f83c1cba3917da0e292078 GIT binary patch literal 621 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdvZCk&zMT zNCaT#;ACWAMim3Pludwvkrm_%W|&eYMv$alJNgq3_L)SnFN^y8SEJ@+m}^K1<$nYk$JXGE!^4FP9?qX(1EPQJ;_rJ zSoQh*&6ieJ-K=)2kYU$EPNkyx2G#T8GR@*8^wK}8FbF-CSwCsJk6PAilUpZdePVoK z$Di+|`1Scl>6p0N{8>9!?p$g4I<0t$LCGeaSC7M8*5@u?=(R)R?XCl5)$dmd=L(fR zWq&-+zGjzYvQ3xC4tjcfKHAV6LcA;YJQ?6W{cgc2*ZJx-t&;_qgDziTkvPxS%Cw#4vOXni? z+QwkR?<;k0wmph;Qp%L;QTn;u)t~clmY2s0JGuI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdv}Sk&zMT zNCW`d&&a@xDh6~Zn*akND+3cFD_l7fBS=_KNRh!%Sd?8!OppO6zywqQGmBA>iJ3vs zki}6bkTtP!;zA|i|F;-;fJQS3G7B=;Gh94>{o9jw#HzR+a0evi2E&q)lNg?-mgMlTb#xq2;g>qOHh z%r|QL`@0klznkH+ZnJdyzofLZSlQWr?#8{+9hLDLPgyl35VPB%NAs9~D*+c(!!Y)Y9L_ylrcy-H%_jdcm$TlaLEtCpzvl zb={e0apKkP8?#v_G#~o$WdFRHRl4%oD_7etsg9`J5&ST$b-hZD{0f!ASxhJX)!fP0 z-th08x6&Z}EP^#W?D%i@AAeBEWp=~A@y?hNM%-Dcm- Tj|yczE6h)u(00vo{r{T)h^V!0 literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_newposts_locked_legenda.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_newposts_locked_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7842b3abb27edc4c8079ca995cef3864347372e0 GIT binary patch literal 621 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdv}Sk&zMT zNCaT#;ACWAMim3Pludwvk%fto1tG)C$i%`X$STC3XvnT4EGj0*z{t$P$jl1Y$|%Uh z43uPX3>0EbY@E1IN%;RQ1|FaROoGgU4E79{>Wl98c(v}6t-8v$KKYVgr_7NXZ=_fC zoj5;*O?1ihuQLzUOx$}|P_XaObJG(u{Wet3i_0{Nm(WZ9timAlSoZqK=w-q-SFdGm zooM=m`HmgGzjq)j*B_M?F`3c+&(gwDGt3&+y-2v3lJm82>&FBRw|4D<7mqb0Pu#26 zd02RIU*KNL$KOvco@TUE$|H_RI<@Za%gl%Frq@mdvG0F*bvFO2HQaftcJI;2Secl0 zvdxmO>!fZ?iqY)J$Bs_uJX)Q4U*>yAlw5FdShdHu4WA2^FIvkU=P6;YF!5Mc-SVm@ zf=T%^vhS@5JiY8Tm!Q3y^c)kDvMuNRBu=TZty*`=e0!hwlr1%RJx+l#Ys-r{iUiZ{ VJ^Qi9*XEq=yG)MUuI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdvxKff?vV zB*4th$p{2UA`A>H%&YNFA@0ULtv-u2buKLS%8Z9r2&c8rDrvPezj=dyZlJ)<1y>E%p4EKobc!WX zYrCkG)g2=dDZKR;|r`6ZFrtvQVY>(1wL}wo>m`e%!%c zdZF&=&2*_p>qYhzo~;k`Ij41Wci)qCHl3ZH?0#Q;%*$o1w_o#_tHWKP4-1P=P0sD! zdnjjW|L4gq4fD*G=2pc$o8=xqVWZfyITO0yE_^-tPM9@wQu_7_%3)6f4NtQBuW#~N z{BGZ2zMZn0T}4VmuU~cLK7P~U@zm#Q`sT0kC{z!f8F@2miGb4;c@wi`&wbCIHu4tK OaAMNnFqh8$e-i-iRII1~ literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_newposts_sticky_alt.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_newposts_sticky_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..600355cd80364d4e0b804bcd6ab35e6f015eab3f GIT binary patch literal 611 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdvZCfteBL zNF>0{!N~{&NFodjEX=F|42&#Hj4X_-FbQTxCKgsfHg*O@Az=|m6;TdOpt+39EKJNW z6~ItpW)NgiOcY`@40L=b{QnjM570IyL1sY)dxpGXxyL7r>le-mUy@aAt{8T_d9}gk z5)PkC)9i>o+1c~6>ie_yX|+@}zf)Mew;@e5;^F?qXRVy}%zpER{cNDX&JAmonzw{U zSk*@G?4Pw(YFlXaWHu*d<9^on_g`N4_}i!QVP@buvG3n>*LUsNG0E*=MASc9>GuKk zs{3b^-oImQd%I7|bZ*Pi3#&4ZuRgX_bDR3XUcHk3IT<{iPZ%bA@)27d6Sn(O-?`Ak z3A^v8os9U;U}@pO`FQR6W!t_lRbF=@qPy77!)!wOoT2K3=tq zd`~R>7^XBx&w92nW~o_J-`8(G$=dTaS=DV+I5IaZH9a+Zf+LrQT~5iiXS3%|OPQt= O(83ZSP%0h%|0V!Yb*cRT literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_newposts_sticky_legenda.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_newposts_sticky_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..868f293809ac3100f8e7d0c95b0000c85179c03f GIT binary patch literal 615 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdvZCfteBL zNCaSH=ip=n0)z;V#lp-gz`)4D#0YdaOoEw_3FvfoK?X%(Ma23E% zVrCFzQA`wKH4JooDE$8x0}s$PCP8LF2789mcRkk=PXFtCHAh|Kl$mTyhQ(?X-|H7< zTza(aqKvh<-HrbYa#w3twJ0^eadiL5a85Mh;r_*EjhyDpe)ER?Y@oo-4Qn;mpI)_Q zzjCa^yXaXPwY=9AY5QDXZ29=c-rv7Ubm}h4RYZkkue$f|=+=+n(}g_lXmiIOUtIf& z_15ZL8~-!hskXTv6Y}UMqj$rV%iUuAIZjXVo26oY%G+Fh+t$}7G%v8}YIfK4ioiRc z)=9J8duZl${O8F-4*s&awWizmYRc9*9f_V*@;+mw>ONzR>CYfhazbzPxJ?7`2Cmu}C>tBafz Q(di^0nBaINH~#-k09`Y)bN~PV literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c766ad35de3bb434a6be2b024a08cc28a7bcf520 GIT binary patch literal 469 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdv)Nk&zMT zNCaSG2|KVGS9~opKOr4cWb%)$xo8kCAM8ybL5jM!_~i8%a8aMv1uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdv83k&zMT zNCaSG7OdW#%Z!z!y)iVh)3o_UcdXdkQ|T|lf4JvPS+e%~0({~-M7t^-Db&rO|I?77Mw0p zU7abTp=4Ret@-uKyq$6e(sySao2|TWc5e5Zu0L@<9n7oa(vC8^lufm`-1U_E!SC1W zYkmlu=50Qb@zJ(hPORQNe?s(?n_KOCsx{WnIA<@Ju;ZiG2?qy-Zw#Ew2map#0NYw- A3;+NC literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_legenda.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_legenda.jpg new file mode 100644 index 0000000000000000000000000000000000000000..86e922d8a9c75f20b8431eb27926588f275512af GIT binary patch literal 468 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdvuJk&zMT zNCaSGc+b}pA05c9cy-HWy29N2?l-62gewH_-Vc|&=n%*}W#zS)aE*BR zy+yX49|c;6X7gBe3)~c3@J36!r|HqWi?cZc*F4&nwBt|ck{utNt_TQl*fuaZd|dqh FCIF!`W*h(j literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_locked.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_locked.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03d3c234c5fc7e0d233d0a6d626a1fb27ae5d5e8 GIT binary patch literal 506 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdv`RkrC)d zB*4zW2n0w1Kqe!T00Sc{0}~@ND@+2&20C1jU5LR@Nl{o?j6)Dpm*D?f3_Q$?K--uF z8SEK$?Y_NT@7dMdSH{2EK34IZos#Bz@|ts?fP%=hXcJ4V%S&!gYM2sL$gn45VnChU zW~KgLo42@p*xP;m+S7R(&e~4jA#;?+*7#d#p>|R@v;V=#MLyd;D?a(YYoV~OP{pUl zmkIIzW*AWiF$7M{m4eE@MKNpuT?rzeD+pe xsl4?f>e=DVFLUCi&)wN`d0{rg$+r1D4ZrvIOnzizwq#jX^P%cWeRKE!Hv!SUfPDY} literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_locked_alt.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_locked_alt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1cf52a0d30cdf1670a1ce4d0d4a46c645463838a GIT binary patch literal 499 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdv83krC)d zB*4zWh%UsyD8RtT3i1LoOffSf6VTm)LQ3omhKkA}9Dqn>(-bjZ_e~QU2R+<@a6dC)!ngTdy;H4&Gk6Wh?SY&T0FuI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdvuJkrC)d zB*4zW2n0w1Kqe!T00Sc{$Pdgg8D>T%pu+{(g_IZ!6_rIe1Tpk5{J+J(160o>$SlZU z&#=9E_txBJm*1|+D0y`3MRAy6lhgT4xjt?VH4}PY{M0hqkuvGHwu?*hp3oC3?#IvM zI{r8HW^Mkx!yXcF v{qWV^y;FS?A|royJk-ur*n2?ou`-|kwUw{#v8`I~>h@uNocGzt`u{fpsKkEX literal 0 HcmV?d00001 diff --git a/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_sticky.jpg b/GUI/App_Themes/LLBLGenPro/pics/icon_nonewposts_sticky.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f84a74f22a8f225a652fb091c64a169a6c7804f3 GIT binary patch literal 511 zcmex=uI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdv%Mff?vV zB*4nf$p{2UB0w)NFbOa)vH&47D@=l!k%^U!MNmqoCsdTMRtR zKm!Ds1sUua>b@_1zES=!-)pPAVdrmLESzAuI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdvfEff?vV zB*4nf!3YFMB0wf1lK=w)8zT!ND_nvRy+q4Atm-nO$|(M9R7BQ zIJg=rHO>^RJ^0k?XycTd5*EQV}26H`_sNH?2caz9QHZ6rnT6t zuFN^UFsvYOsmoF2c&|if{}oqvx1VmldZRgsOH*U>)JginE7(|ee!Ai_)09iJGkYh` srJr6m^|giOp2&KC$Zpx>N1VGmt_C_RSK!YV)?RuI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVVBlxqXJ!;+U=n0x7G(T?gdvfEff?vV zB*4nf$p{2UB0w)NFbOa)vM{nRF~cR88JU1C7gQ8t7v^AaRN@o_>OnP%QBaZT|1Aa{ zpdKbcW->KrRKN6PT z-?-)PCH?GYse7w-EWEYD*Vn`F;hnujOs@TEm6r-1EJ@Q~arQKbKKjI6Vdtl-F=p8l zovP}k-k5HATeIojy*ZV$H+qX*f8;dJG{jg*)ZzM8@zY0-UjMSjci*;qTkZef1OQm& Ben9{L literal 0 HcmV?d00001 diff --git a/GUI/ApproveAttachments.aspx b/GUI/ApproveAttachments.aspx new file mode 100644 index 0000000..25e0e2c --- /dev/null +++ b/GUI/ApproveAttachments.aspx @@ -0,0 +1,131 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ApproveAttachments.aspx.cs" Inherits="SD.HnD.GUI.ApproveAttachments" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="MessageEditor" Src="MessageEditor.ascx"%> +<%@ Import Namespace="System.Globalization" %> +<%@ Import Namespace="SD.HnD.GUI" %> +<%@ Import Namespace="SD.HnD.BL" %> + + + + HnD::Manage attachments + + + + + +
    + + + + + +
    +
    + You are here: Home > Approve Attachments +

    +
    + + + + + +
    +

    Approve attachments

    + Below you'll find the all the attachments which need approval. The messages to which they're attached are reachable as well. Be sure you've + checked the attachment's contents to see if it can be approved or not when you click the Approve button for a given attachment. Only approve attachments + which you find OK for visitors to download. + +

    + You're allowed to delete attachments as well. It's best to delete an attachment if the attachment will never get approval, as it will otherwise + stick around forever in this list. An attachment which violates certain forum rules will likely fall into this category. +
    +
    +
    + + + + + + + + + + +
    + Message Attachments +
    + The list of attachments which need approval. +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     FilenameFile sizeAdded onApproval
    + +   + + <%# Eval("Filename") %> +
    +
    + Attached to message: #<%# Eval("MessageID") %> +
    +
    <%# ((int)Eval("Filesize")).ToString("N0") %><%# ((DateTime)Eval("AddedOn")).ToString("dd-MMM-yyyy HH:mm.ss", DateTimeFormatInfo.InvariantInfo) %> + +
    + +   + + <%# Eval("Filename") %> +
    +
    + Attached to message: #<%# Eval("MessageID") %> +
    +
    <%# ((int)Eval("Filesize")).ToString("N0") %><%# ((DateTime)Eval("AddedOn")).ToString("dd-MMM-yyyy HH:mm.ss", DateTimeFormatInfo.InvariantInfo) %> + +
    + +
    +
    +
    +
    + + + + diff --git a/GUI/ApproveAttachments.aspx.cs b/GUI/ApproveAttachments.aspx.cs new file mode 100644 index 0000000..955b0e6 --- /dev/null +++ b/GUI/ApproveAttachments.aspx.cs @@ -0,0 +1,99 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.CollectionClasses; +using System.IO; +using System.Collections.Generic; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file for the ApproveAttachments form + /// + public partial class ApproveAttachments : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + // check if the calling user is able to approve attachments in 1 or more forums + List forumsWithApprovalRight = SessionAdapter.GetForumsWithActionRight(ActionRights.ApproveAttachment); + List accessableForums = SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum); + if(((forumsWithApprovalRight == null) || (forumsWithApprovalRight.Count <= 0))|| + ((accessableForums== null) || (accessableForums.Count <= 0))) + { + // no, this user doesn't have the right to approve attachments or doesn't have access to any forums. + Response.Redirect("default.aspx", true); + } + + List forumsWithAttachmentDeleteRight = SessionAdapter.GetForumsWithActionRight(ActionRights.ManageOtherUsersAttachments); + phAttachmentDelete.Visible = ((forumsWithAttachmentDeleteRight!=null) && (forumsWithAttachmentDeleteRight.Count>0)); + + if(!Page.IsPostBack) + { + // get all attachments which aren't approved yet as a dataview. + DataView allAttachmentsToApprove = MessageGuiHelper.GetAllAttachmentsToApproveAsDataView(accessableForums, + forumsWithApprovalRight, SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), + SessionAdapter.GetUserID()); + rpAttachments.DataSource = allAttachmentsToApprove; + rpAttachments.DataBind(); + } + } + + + /// + /// Handles the ItemCommand event of the rpAttachments control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void rpAttachments_ItemCommand(object source, RepeaterCommandEventArgs e) + { + int attachmentID = HnDGeneralUtils.TryConvertToInt((string)e.CommandArgument); + + switch(e.CommandName) + { + case "Approve": + // if auditing is required, we've to do this now. + if(SessionAdapter.CheckIfNeedsAuditing(AuditActions.AuditApproveAttachment)) + { + SecurityManager.AuditApproveAttachment(SessionAdapter.GetUserID(), attachmentID); + } + MessageManager.ModifyAttachmentApproval(attachmentID, true); + break; + case "Delete": + MessageManager.DeleteAttachment(attachmentID); + break; + } + + // done, refresh through redirect to self + Response.Redirect("ApproveAttachments.aspx", true); + } + } +} \ No newline at end of file diff --git a/GUI/AssemblyInfo.cs b/GUI/AssemblyInfo.cs new file mode 100644 index 0000000..6d050bc --- /dev/null +++ b/GUI/AssemblyInfo.cs @@ -0,0 +1,80 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("HnD.GUI")] +[assembly: AssemblyDescription("HnD's GUI")] +[assembly: AssemblyCompany("Solutions Design")] +[assembly: AssemblyProduct( "HnD, a .NET 2.0 Customer support system using LLBLGen Pro" )] +[assembly: AssemblyCopyright( "(c)2002-2006 Solutions Design" )] +[assembly: AssemblyTrademark( "HnD, LLBLGen and LLBLGen Pro are trademarks of Solutions Design." )] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("2.0.0.0")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the "project output directory". The location of the project output +// directory is dependent on whether you are working with a local or web project. +// For local projects, the project output directory is defined as +// \obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// For web projects, the project output directory is defined as +// %HOMEPATH%\VSWebCache\\\obj\. +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/GUI/Attachments.aspx b/GUI/Attachments.aspx new file mode 100644 index 0000000..1fb7072 --- /dev/null +++ b/GUI/Attachments.aspx @@ -0,0 +1,153 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Attachments.aspx.cs" Inherits="SD.HnD.GUI.Attachments" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="MessageEditor" Src="MessageEditor.ascx"%> +<%@ Import Namespace="System.Globalization" %> + + + + HnD::Manage attachments + + + + + +
    + + + + + +
    +
    + You are here: Home > > + > + > Attachments +

    +
    + + + + + +
    +

    Attachments

    + Below you'll find the attachments for the message reachable by the following URL:
    + Direct link to message # + +

    + Max. # of attachments per message:
    + Max. file size of attachment: +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + Message Attachments +
    + The list of attachments of the selected message. +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     FilenameFile sizeAdded onApproval
    +   + + <%# Eval("Filename") %> + <%# Eval("Filename") %> + <%# ((int)Eval("Filesize")).ToString("N0") %><%# ((DateTime)Eval("AddedOn")).ToString("dd-MMM-yyyy HH:mm.ss", DateTimeFormatInfo.InvariantInfo) %> + + + + +
    +   + + <%# Eval("Filename") %> + <%# Eval("Filename") %> + <%# ((int)Eval("Filesize")).ToString("N0") %><%# ((DateTime)Eval("AddedOn")).ToString("dd-MMM-yyyy HH:mm.ss", DateTimeFormatInfo.InvariantInfo)%> + + + + +
    + +
    +
    +
    + Add a new attachment:    + +
    +
    + + +
    +

    +
    + +
    +
    +
    + + + + diff --git a/GUI/Attachments.aspx.cs b/GUI/Attachments.aspx.cs new file mode 100644 index 0000000..53f0099 --- /dev/null +++ b/GUI/Attachments.aspx.cs @@ -0,0 +1,343 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.CollectionClasses; +using System.IO; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file for the Attachments form + /// + public partial class Attachments : System.Web.UI.Page + { + #region Class Member Declarations + private int _sourceType, _numberOfAttachments; + private MessageEntity _message; + private ThreadEntity _thread; + private ForumEntity _forum; + private bool _userCanApproveAttachments, _userCanAddAttachments, _userMayManageAttachments; + #endregion + + protected void Page_Load(object sender, EventArgs e) + { + int messageID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["MessageID"]); + _message = MessageGuiHelper.GetMessage(messageID); + if(_message == null) + { + // not found + Response.Redirect("default.aspx", true); + } + + _sourceType = HnDGeneralUtils.TryConvertToInt(Request.QueryString["SourceType"]); + switch(_sourceType) + { + case 1: + // new message, or message view, for now no action needed + break; + case 2: + // new thread, for now no action needed + break; + default: + // unknown, redirect + Response.Redirect("default.aspx", true); + break; + } + + // We could have used Lazy loading here, but for the sake of separation, we use the BL method. + _thread = ThreadGuiHelper.GetThread(_message.ThreadID); + if(_thread == null) + { + // not found. Orphaned message. + Response.Redirect("default.aspx", true); + } + + _forum = CacheManager.GetForum(_thread.ForumID); + if(_forum == null) + { + // not found. + Response.Redirect("default.aspx", true); + } + + // check if this forum accepts attachments. + if(_forum.MaxNoOfAttachmentsPerMessage <= 0) + { + // no, so no right to be here nor is the user here via a legitimate route. + Response.Redirect("default.aspx", true); + } + + // Check credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx", true); + } + + // check if the user can view this thread. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !_thread.IsSticky) + { + // can't view this thread, it isn't visible to the user + Response.Redirect("default.aspx", true); + } + + // Check if the current user is allowed to manage attachments of this message, and other rights. + _userMayManageAttachments = ((_message.PostedByUserID==SessionAdapter.GetUserID())|| + SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ManageOtherUsersAttachments)); + _userCanAddAttachments = (((_message.PostedByUserID==SessionAdapter.GetUserID()) || + SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ManageOtherUsersAttachments)) && + SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAttachment)); + _userCanApproveAttachments = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ApproveAttachment); + + phAttachmentLimits.Visible = _userMayManageAttachments; + + if(!Page.IsPostBack) + { + // fill the page's content + lnkThreads.Text = HttpUtility.HtmlEncode(_forum.ForumName); + lnkThreads.NavigateUrl += "?ForumID=" + _thread.ForumID; + lblSectionName.Text = CacheManager.GetSectionName(_forum.SectionID); + lnkMessages.NavigateUrl += _message.ThreadID; + lnkMessages.Text = HttpUtility.HtmlEncode(_thread.Subject); + + lblMaxFileSize.Text = String.Format("{0} KB", _forum.MaxAttachmentSize); + lblMaxNoOfAttachmentsPerMessage.Text = _forum.MaxNoOfAttachmentsPerMessage.ToString(); + lnkMessage.Text += messageID.ToString(); + lnkMessage.NavigateUrl += String.Format("MessageID={0}&ThreadID={1}", messageID, _thread.ThreadID); + + phAddNewAttachment.Visible = _userCanAddAttachments; + + BindAttachments(); + } + else + { + object numberOfAttachments = ViewState["numberOfAttachments"]; + if(numberOfAttachments != null) + { + _numberOfAttachments = (int)numberOfAttachments; + } + } + } + + + /// + /// Binds the attachments. + /// + private void BindAttachments() + { + // get all attachments for the given message and bind them to the repeater + DataView attachments = MessageGuiHelper.GetAttachmentsAsDataView(_message.MessageID); + + rpAttachments.DataSource = attachments; + rpAttachments.DataBind(); + + // if max number of attachments has been reached, disable the add attachment placeholder + if(_forum.MaxNoOfAttachmentsPerMessage <= attachments.Count) + { + // maximum has been reached + phAddNewAttachment.Visible = false; + } + else + { + phAddNewAttachment.Visible = _userCanAddAttachments; + } + + _numberOfAttachments = attachments.Count; + ViewState["numberOfAttachments"] = _numberOfAttachments; + } + + + /// + /// Handles the ItemCommand event of the rpAttachments control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void rpAttachments_ItemCommand(object source, RepeaterCommandEventArgs e) + { + int attachmentID = HnDGeneralUtils.TryConvertToInt((string)e.CommandArgument); + + switch(e.CommandName) + { + case "Approve": + if(_userCanApproveAttachments) + { + // if auditing is required, we've to do this now. + if(SessionAdapter.CheckIfNeedsAuditing(AuditActions.AuditApproveAttachment)) + { + SecurityManager.AuditApproveAttachment(SessionAdapter.GetUserID(), attachmentID); + } + MessageManager.ModifyAttachmentApproval(attachmentID, true); + } + break; + case "Revoke": + if(_userCanApproveAttachments) + { + MessageManager.ModifyAttachmentApproval(attachmentID, false); + } + break; + case "Delete": + if(_userMayManageAttachments) + { + MessageManager.DeleteAttachment(attachmentID); + } + break; + } + + phUploadResult.Visible = false; + + // rebind attachments. + BindAttachments(); + } + + + /// + /// Handles the Click event of the btnUploadAttachment control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void btnUploadAttachment_Click(object sender, EventArgs e) + { + if(!_userCanAddAttachments) + { + // can't add attachments + return; + } + + if(!phAddNewAttachment.Visible) + { + // custom http put request, deny + return; + } + + if(_numberOfAttachments>=_forum.MaxNoOfAttachmentsPerMessage) + { + // # of attachments is already on maximum. Deny + phUploadResult.Visible = true; + lblError.Visible = true; + lblSuccess.Visible=false; + lblError.Text = String.Format("You can't add another attachment to this message. Maximum # of attachments per message: {0}. Current # of attachments: {1}", _forum.MaxNoOfAttachmentsPerMessage, _numberOfAttachments); + return; + } + + byte[] fileContents = fuUploader.FileBytes; + int lengthInKB = fileContents.Length / 1024; + if(_forum.MaxAttachmentSize < (lengthInKB)) + { + // attachment is too big + phUploadResult.Visible = true; + lblError.Visible = true; + lblSuccess.Visible=false; + lblError.Text = String.Format("The attachment is too big. Maximum size: {0} KB. Attachment size: {1} KB", _forum.MaxAttachmentSize, lengthInKB); + return; + } + + if(fileContents.Length <= 0) + { + // file is empty + phUploadResult.Visible = true; + lblError.Visible = true; + lblSuccess.Visible = false; + lblError.Text = "The attachment is empty, the size is 0 bytes."; + return; + } + + string fileName = Path.GetFileName(fuUploader.FileName); + + if(fileName.Length > 255) + { + // too big, chop off + fileName = fileName.Substring(fileName.Length - 200); + } + + MessageManager.AddAttachment(_message.MessageID, fileName, fileContents, SessionAdapter.CanPerformForumActionRight(_forum.ForumID, ActionRights.GetsAttachmentsApprovedAutomatically)); + phUploadResult.Visible = true; + lblError.Visible = false; + lblSuccess.Visible = true; + lblSuccess.Text = string.Format("Upload of attachment '{0}' with size {1} was successful.", fileName, fileContents.Length.ToString("N0")); + + BindAttachments(); + } + + + /// + /// Handles the Click event of the btnContinue control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void btnContinue_Click(object sender, EventArgs e) + { + // depending on the sourcetype, we're going to redirect to a different page. + switch(_sourceType) + { + case 1: + // message list oriented, redirect to the message set + Response.Redirect(String.Format("GotoMessage.aspx?MessageID={0}&ThreadID={1}", _message.MessageID, _message.ThreadID), true); + break; + case 2: + // thread list oriented, redirect to thread list + Response.Redirect("Threads.aspx?ForumID=" + _forum.ForumID, true); + break; + default: + // unknown + Response.Redirect("default.aspx", true); + break; + } + } + + + #region Class Property Declarations + /// + /// Gets a value indicating whether [user can approve attachments]. + /// + /// + /// true if [user can approve attachments]; otherwise, false. + /// + protected bool UserCanApproveAttachments + { + get { return _userCanApproveAttachments; } + } + + /// + /// Gets a value indicating whether [user may manage attachments]. + /// + /// + /// true if [user may manage attachments]; otherwise, false. + /// + protected bool UserMayManageAttachments + { + get { return _userMayManageAttachments; } + } + #endregion + } +} \ No newline at end of file diff --git a/GUI/Bookmarks.aspx b/GUI/Bookmarks.aspx new file mode 100644 index 0000000..1be4e65 --- /dev/null +++ b/GUI/Bookmarks.aspx @@ -0,0 +1,126 @@ +<%@ Page language="c#" CodeFile="Bookmarks.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Bookmarks" %> +<%@ Import namespace="System.Data" %> +<%@ Import namespace="System.Web" %> +<%@ Import Namespace="SD.HnD.GUI" %> +<%@ Import Namespace="System.Globalization" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageList" Src="PageList.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageLegend" Src="PageLegend.ascx"%> + + + + HnD::Bookmarked threads + + + +
    + + + + + +
    +
    + You are here: Home > My bookmarks +

    +
    + + + + + + + + + + + + +
    + My bookmarks +
    + The list of your bookmarked threads. +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Thread subjectRepliesViewsLast post
    + + + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +     +
    Posted in forum: <%# Eval("ForumName")%>.
    Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    +
    <%# (int)Eval("AmountMessages") - 1%><%# Eval("NumberOfViews")%> +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On:
    +
    + + + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +     +
    Posted in forum: <%# Eval("ForumName")%>.
    Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    +
    <%# (int)Eval("AmountMessages") - 1%><%# Eval("NumberOfViews")%> +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On:
    +
    + +
    +
    +   +
    +
    + +
    +
    + + + + diff --git a/GUI/Bookmarks.aspx.cs b/GUI/Bookmarks.aspx.cs new file mode 100644 index 0000000..0beab8c --- /dev/null +++ b/GUI/Bookmarks.aspx.cs @@ -0,0 +1,168 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; + +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// Code behind for Bookmarks thread viewer / editor form. + /// + public partial class Bookmarks : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // fill the page's content + DataView bookmarks = UserGuiHelper.GetBookmarksAsDataView(SessionAdapter.GetUserID()); + + rpThreads.DataSource = bookmarks; + rpThreads.DataBind(); + + btnRemoveChecked.Visible=(bookmarks.Count>0); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.rpThreads.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.rpThreads_ItemDataBound); + this.btnRemoveChecked.Click += new System.EventHandler(this.btnRemoveChecked_Click); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + + /// + /// Event handler which will be called every time a row in the Repeater rpThreads is bound to a row in the view. + /// + /// + /// + private void rpThreads_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + // Thread has always a last posting date: a thread has at least 1 posting. + DateTime threadLastPostingDate = (DateTime)(((DataRowView)e.Item.DataItem)["ThreadLastPostingDate"]); + DateTime lastVisitDate = SessionAdapter.GetLastVisitDate(); + bool isSticky = (bool)(((DataRowView)e.Item.DataItem)["IsSticky"]); + bool isClosed = (bool)(((DataRowView)e.Item.DataItem)["IsClosed"]); + bool bMarkedAsDone = (bool)(((DataRowView)e.Item.DataItem)["MarkedAsDone"]); + + // date is not 0, check if the date is > than the date in the session variable. If so, the posting is newer and we + // should visualize the New Messages image, otherwise the No new Messages image. Also take into account + // the type of the thread: sticky, closed or normal. + System.Web.UI.WebControls.Image imgIconPosts; + + if (threadLastPostingDate > lastVisitDate) + { + // there are new messages since last visit + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPosts"); + } + } + } + else + { + // no new messages + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPosts"); + } + } + } + imgIconPosts.Visible=true; + break; + } + } + + private void btnRemoveChecked_Click(object sender, System.EventArgs e) + { + ArrayList threadIDsToRemove = new ArrayList(); + + // each checked bookmarked thread has to be removed from the + for (int i = 0; i < rpThreads.Items.Count; i++) + { + CheckBox chkRemoveFromBookmarks = (CheckBox)rpThreads.Items[i].FindControl("chkRemoveFromBookmarks"); + if(chkRemoveFromBookmarks.Checked) + { + threadIDsToRemove.Add(HnDGeneralUtils.TryConvertToInt(chkRemoveFromBookmarks.Attributes["ThreadID"])); + } + } + + if(threadIDsToRemove.Count>0) + { + // remove the threads from the bookmarks. + UserManager.RemoveBookmarks(threadIDsToRemove, SessionAdapter.GetUserID()); + } + + Response.Redirect("Bookmarks.aspx"); + } + } +} diff --git a/GUI/CREDITS.txt b/GUI/CREDITS.txt new file mode 100644 index 0000000..349ff20 --- /dev/null +++ b/GUI/CREDITS.txt @@ -0,0 +1,33 @@ +HnD Copyright and credits +========================== + +Copyright +========= +HnD is (c) 2002-2008 Solutions Design. +http://www.llblgen.com +http://www.sd.nl + +HnD is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as published by +the Free Software Foundation. + +HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Credits +======= +Main programming and design: + - Frans Bouma + +Additional programming and design: + - Walaa Atef + - Jean-Sylvain Boige + - Todd Price + - Aglaia Kuipers \ No newline at end of file diff --git a/GUI/CloseThread.aspx b/GUI/CloseThread.aspx new file mode 100644 index 0000000..2d055d6 --- /dev/null +++ b/GUI/CloseThread.aspx @@ -0,0 +1,38 @@ +<%@ Page language="c#" CodeFile="CloseThread.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.CloseThread" ValidateRequest="false" Async="true"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="MessageEditor" Src="MessageEditor.ascx"%> + + + + HnD::Close the thread: <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> + + + + + +
    + + +
    +
    + + + + +
    +

    Close thread

    +

    + Below you can edit the text for the close message of the thread <%=HttpUtility.HtmlEncode(base.ThreadSubject)%>. When you click + Post, the close message is added to the thread and the thread is closed so no more messages can be added to the + thread. +

    +
    +
    + + +
    + + + + diff --git a/GUI/CloseThread.aspx.cs b/GUI/CloseThread.aspx.cs new file mode 100644 index 0000000..4cb979f --- /dev/null +++ b/GUI/CloseThread.aspx.cs @@ -0,0 +1,189 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file for the CloseThread form + /// + public partial class CloseThread : System.Web.UI.Page + { + #region Class Member Declarations + private int _startAtMessageIndex; + private ThreadEntity _thread; + #endregion + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread == null) + { + // not found, return to default page + Response.Redirect("default.aspx", true); + } + + _startAtMessageIndex = HnDGeneralUtils.TryConvertToInt(Request.QueryString["StartAtMessage"]); + + if(_thread.IsClosed) + { + // is already closed + Response.Redirect("default.aspx", true); + } + + // Check access credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + bool userMayDoThreadManagement = SessionAdapter.HasSystemActionRight(ActionRights.ForumSpecificThreadManagement)|| + SessionAdapter.HasSystemActionRight(ActionRights.SystemWideThreadManagement); + + if(!userHasAccess || !userMayDoThreadManagement) + { + // doesn't have access to this forum or may not alter the thread's properties. redirect + Response.Redirect("default.aspx", true); + } + + // check if the user can view this thread. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !_thread.IsSticky) + { + // can't view this thread, it isn't visible to the user + Response.Redirect("default.aspx", true); + } + + bool userMayAddNewMessages = false; + if(!_thread.IsClosed) + { + if(_thread.IsSticky) + { + if(SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAndEditMessageInSticky)) + { + userMayAddNewMessages = true; + } + } + else + { + if(SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAndEditMessage)) + { + userMayAddNewMessages = true; + } + } + } + + if(!userMayAddNewMessages) + { + // is not allowed to post a new message. This forum allows the user to add a new message and close the thread at the same time. + // deny. + Response.Redirect("default.aspx", true); + } + + if(!Page.IsPostBack) + { + // fill the page's content + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // Orphaned thread + Response.Redirect("default.aspx", true); + } + meMessageEditor.ForumName = forum.ForumName; + meMessageEditor.ThreadSubject = _thread.Subject; + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + protected void PostMessageHandler(object sender, System.EventArgs e) + { + string mailTemplate = ApplicationAdapter.GetEmailTemplate(EmailTemplate.ThreadUpdatedNotification); + // store the new message in the given thread and close it directly. + int messageID = ThreadManager.CreateNewMessageInThreadAndCloseThread(_thread.ThreadID, SessionAdapter.GetUserID(), meMessageEditor.MessageText, + meMessageEditor.MessageTextHTML, Request.UserHostAddress.ToString(), meMessageEditor.MessageTextXML, + mailTemplate, ApplicationAdapter.GetEmailData(), CacheManager.GetSystemData().SendReplyNotifications); + + // all ok, redirect to message list + int startAtMessageID = ThreadGuiHelper.GetStartAtMessageForGivenMessageAndThread(_thread.ThreadID, messageID, SessionAdapter.GetUserDefaultNumberOfMessagesPerPage()); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + startAtMessageID + "&#" + messageID, true); + } + + protected void CancelActionHandler(object sender, System.EventArgs e) + { + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startAtMessageIndex, true); + } + + + #region Class Property Declarations + /// + /// Gets the thread subject. + /// + /// The thread subject. + protected string ThreadSubject + { + get + { + string toReturn = string.Empty; + if(_thread != null) + { + toReturn = _thread.Subject; + } + return toReturn; + } + } + #endregion + } +} diff --git a/GUI/Default.aspx b/GUI/Default.aspx new file mode 100644 index 0000000..6f856e9 --- /dev/null +++ b/GUI/Default.aspx @@ -0,0 +1,222 @@ +<%@ Page language="c#" CodeFile="default.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI._default" EnableViewState="false" %> +<%@ Import namespace="System.Data" %> +<%@ Import namespace="SD.HnD.DAL.EntityClasses" %> +<%@ Import Namespace="SD.HnD.GUI" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> + + + + HnD:: + + +
    + + + + + + +
    +
    + + + + + +
      +
    + Welcome ! +
    + + Below, you'll find several sections and forums where you can discuss all kinds of topics, if + you're a registered user and if you've logged in. +
    + If you're not a registered user, you can register here. +
    + + Below you'll find several sections and forums where you can discuss all kinds of topics. + +

    + + Your last session here started on: +

    +
    + + + There are attachments waiting for approval.
    +
    + + There are threads waiting in the support queues.
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + +
    + <%#Eval("SectionName")%> +
    + <%#Eval("SectionDescription")%> +
    + +
    + ');">  +
    +
    +
    +
    "> + + + + + + + + + + + + + +
     ForumThreadsPostsLast post
    + + + +
    + + + +    <%# Eval("ForumName")%>
    + <%# Eval("ForumDescription")%> +
    <%# Eval("AmountThreads")%><%# Eval("AmountMessages")%>
    + + +    <%# Eval("ForumName")%>
    + <%# Eval("ForumDescription")%> +
    <%# Eval("AmountThreads")%><%# Eval("AmountMessages")%>
     
     
    + +
    + + + + + + + + +
    + Easy Access +
    + + + + + + + + + + + + + + + + + + + + + + +
      ThreadsPostsLast post
    + + + +  View / edit my bookmarks
    +  Enables you to view / edit the list of your bookmarked threads. +
    + + + +  View active threads
    +  Enables you to view all active threads of the past <%=CacheManager.GetSystemData().HoursThresholdForActiveThreads%> hours. +
    +
     
    +
    + + + + + + + + + + + + + + + +
    +  Legend: +
     No new messages since your last visit
     New messages since your last visit
    +
    +
    + + + + + diff --git a/GUI/Default.aspx.cs b/GUI/Default.aspx.cs new file mode 100644 index 0000000..81bc0b9 --- /dev/null +++ b/GUI/Default.aspx.cs @@ -0,0 +1,333 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Web.Security; +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL; +using SD.LLBLGen.Pro.ORMSupportClasses; +using SD.HnD.DAL.HelperClasses; +using System.IO; +using System.Text; + +namespace SD.HnD.GUI +{ + /// + /// Default entrance page for the forum system. + /// + public partial class _default : System.Web.UI.Page + { + #region Class Member Declarations + private Dictionary _forumViewsPerDisplayedSection; + private SectionCollection _sectionsToDisplay; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + if(!Page.IsPostBack) + { + this.Title += ApplicationAdapter.GetSiteName(); + + // first time loaded, fill in properties + lblUserName.Text = SessionAdapter.GetUserNickName(); + + HttpContext hcCurrent = HttpContext.Current; + DataTable bookmarkStatistics = null; + + // check if user is authenticated + if(hcCurrent.Request.IsAuthenticated) + { + lblWelcomeTextLoggedIn.Visible=true; + bookmarkStatistics = UserGuiHelper.GetBookmarkStatisticsAsDataTable(SessionAdapter.GetUserID()); + } + else + { + lblWelcomeTextNotLoggedIn.Visible=true; + bookmarkStatistics = new DataTable(); + } + + // check if the user has the action right to approve attachments on some forum. If so, show the # of attachments which need approval + List forumsWithApprovalRight = SessionAdapter.GetForumsWithActionRight(ActionRights.ApproveAttachment); + bool canApproveAttachments = ((forumsWithApprovalRight != null) && (forumsWithApprovalRight.Count > 0)); + if(canApproveAttachments) + { + int numberOfAttachmentsToApprove = MessageGuiHelper.GetTotalNumberOfAttachmentsToApprove( + SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum), + SessionAdapter.GetForumsWithActionRight(ActionRights.ApproveAttachment), + SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), SessionAdapter.GetUserID()); + if(numberOfAttachmentsToApprove>0) + { + phAttachmentsToApprove.Visible=true; + phAttentionRemarks.Visible = true; + } + } + if(SessionAdapter.HasSystemActionRight(ActionRights.QueueContentManagement)) + { + int numberOfThreadsInSupportQueues = SupportQueueGuiHelper.GetTotalNumberOfThreadsInSupportQueues( + SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum)); + if(numberOfThreadsInSupportQueues > 0) + { + phThreadsToSupport.Visible = true; + phAttentionRemarks.Visible = true; + } + } + + DateTime lastVisitDate = SessionAdapter.GetLastVisitDate(); + + if(SessionAdapter.IsLastVisitDateValid()) + { + phLastVisitDate.Visible=true; + lblLastVisitDate.Text = lastVisitDate.ToString("dd-MMM-yyyy HH:mm"); + } + + // Get all sections which possibly can be displayed. Obtain this from the cache, as it's hardly changing data, and + // this page is read a lot. + _sectionsToDisplay = CacheManager.GetAllSections(); + + // Per section, create a view with all the forumdata and filter out the forums not visible for the current user. + List accessableForums = SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum); + List forumsWithThreadsFromOthers = SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers); + _forumViewsPerDisplayedSection = ForumGuiHelper.GetAllAvailableForumsDataViews(_sectionsToDisplay, accessableForums, + forumsWithThreadsFromOthers, SessionAdapter.GetUserID()); + + // filter out sections which do not have displayable forums for this user + EntityView sectionsToUse = CreateFilteredSectionsCollection(); + + // show the sections with displayable forums, thus the displayable sections. + rpSections.DataSource = sectionsToUse; + rpSections.DataBind(); + + // get bookmarks and show them in the gui + if((bookmarkStatistics.Rows.Count<=0)||((bookmarkStatistics.Rows.Count==1)&&((int)bookmarkStatistics.Rows[0][0]==0))) + { + // no bookmarks yet + lblAmountBookmarks.Text = "0"; + lblAmountPostingsInBookmarks.Text = "0"; + lblBookmarksLastPostingDate.Text = "Never"; + imgIconBookmarkNoNewPosts.Visible=true; + } + else + { + lblAmountBookmarks.Text = bookmarkStatistics.Rows[0]["AmountThreads"].ToString(); + lblAmountPostingsInBookmarks.Text = bookmarkStatistics.Rows[0]["AmountPostings"].ToString(); + DateTime dateLastPosting = (DateTime)bookmarkStatistics.Rows[0]["LastPostingDate"]; + lblBookmarksLastPostingDate.Text = dateLastPosting.ToString("dd-MMM-yyyy HH:mm"); + if (dateLastPosting > lastVisitDate) + { + imgIconBookmarkNewPosts.Visible=true; + } + else + { + imgIconBookmarkNoNewPosts.Visible=true; + } + } + + DataTable activeThreadsStatistics = ThreadGuiHelper.GetActiveThreadsStatisticsAsDataTable(accessableForums, + CacheManager.GetSystemData().HoursThresholdForActiveThreads, + SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), SessionAdapter.GetUserID()); + if (activeThreadsStatistics != null) + { + if ((activeThreadsStatistics.Rows.Count <= 0) || ((activeThreadsStatistics.Rows.Count == 1) && ((int)activeThreadsStatistics.Rows[0][0] == 0))) + { + lblAmountActiveThreads.Text = "0"; + lblAmountPostingsInActiveThreads.Text = "0"; + lblActiveThreadsLastPostingDate.Text = "Never"; + imgIconActiveThreadsNoNewPosts.Visible = true; + } + else + { + lblAmountActiveThreads.Text = activeThreadsStatistics.Rows[0]["AmountThreads"].ToString(); + lblAmountPostingsInActiveThreads.Text = activeThreadsStatistics.Rows[0]["AmountPostings"].ToString(); + DateTime dateLastPosting = (DateTime)activeThreadsStatistics.Rows[0]["LastPostingDate"]; + lblActiveThreadsLastPostingDate.Text = dateLastPosting.ToString("dd-MMM-yyyy HH:mm"); + if (dateLastPosting > lastVisitDate) + { + imgIconActiveThreadsNewPosts.Visible = true; + } + else + { + imgIconActiveThreadsNoNewPosts.Visible = true; + } + } + } + } + + RegisterCollapseExpandClientScript(); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + /// + /// Registers the collapse expand client script. + /// + private void RegisterCollapseExpandClientScript() + { + StringBuilder script = new StringBuilder(File.ReadAllText(Path.Combine(ApplicationAdapter.GetDataFilesMapPath(), "CollapseExpandScript.template"))); + script.Replace("[RootCookieName]", ApplicationAdapter.GetSiteName()); + ClientScriptManager scriptManager = this.ClientScript; + Type typeToUse = this.GetType(); + if(!scriptManager.IsStartupScriptRegistered("CollapseExpandScript")) + { + // register + scriptManager.RegisterStartupScript(typeToUse, "CollapseExpandScript", script.ToString(), true); + } + } + + + /// + /// Creates an EntityView on _sectionsToDisplay with a filter so that empty sections aren't visible. + /// + private EntityView CreateFilteredSectionsCollection() + { + List sectionIDsToFilter = new List(); + // pair.Key is sectionID, pair.Value is DataView with foruminformation + statistics for all the forums in that section. + foreach(KeyValuePair pair in _forumViewsPerDisplayedSection) + { + if(pair.Value.Count <= 0) + { + // empty section, remove it from section list. Since this section list is used to look up forumviews in + // _forumViewsPerDisplayedSection, we don't have to remove the empty dataview here. Simply add the sectionID (==pair.Key) to the + // list of sectionids to filter + sectionIDsToFilter.Add(pair.Key); + } + } + + // create a view on the sections to display and filter the view with a filter on sectionid: a sectionid must not be part of sectionIDsToFilter. + // if there are no sections to filter out, simply don't pass a filter. + if(sectionIDsToFilter.Count <= 0) + { + return new EntityView(_sectionsToDisplay); + } + else + { + return new EntityView(_sectionsToDisplay, (SectionFields.SectionID != sectionIDsToFilter)); + } + } + + + /// + /// Handles the ItemDataBound event of the rpSections control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void rpSections_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + // get the forumlist and bind it to the repeatercontrol created. + SectionEntity currentSection = (SectionEntity)e.Item.DataItem; + DataView forumsView = _forumViewsPerDisplayedSection[currentSection.SectionID]; + + // Find repeater control in this item + Repeater rpForums = (Repeater)e.Item.FindControl("rpForums"); + + // bind it + rpForums.DataSource = forumsView; + rpForums.DataBind(); + break; + } + } + + + /// + /// Handles the ItemDataBound event of the rpForums control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void rpForums_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + { + Label forumLastPostingDateLabel = (Label)e.Item.FindControl("lblForumLastPostingDate"); + + // check if date is NULL + if(((DataRowView)e.Item.DataItem)["ForumLastPostingDate"] is System.DBNull) + { + forumLastPostingDateLabel.Text = "Never"; + + // Date is null, there are no messages. + System.Web.UI.WebControls.Image noNewPostsIcon = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPosts"); + noNewPostsIcon.Visible = true; + } + else + { + HttpContext hcCurrent = HttpContext.Current; + DateTime forumLastPostingDate = (DateTime)(((DataRowView)e.Item.DataItem)["ForumLastPostingDate"]); + DateTime lastVisitDate = SessionAdapter.GetLastVisitDate(); + + forumLastPostingDateLabel.Text = forumLastPostingDate.ToString("dd-MMM-yyyy HH:mm"); + + // date is not 0, check if the date is > than the date in the session variable. If so, the posting is newer and we + // should visualize the New Messages image, otherwise the No new Messages image. + System.Web.UI.WebControls.Image postsIcon; + + if(forumLastPostingDate > lastVisitDate) + { + // there are new messages since last visit + postsIcon = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPosts"); + } + else + { + // no new messages + postsIcon = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPosts"); + } + postsIcon.Visible = true; + } + } + break; + } + } + } +} diff --git a/GUI/DeleteMessage.aspx b/GUI/DeleteMessage.aspx new file mode 100644 index 0000000..634d219 --- /dev/null +++ b/GUI/DeleteMessage.aspx @@ -0,0 +1,82 @@ +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Page language="c#" CodeFile="DeleteMessage.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.DeleteMessage" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> + + + + HnD::Delete a message + + + +
    + + +
    +

    + + + + +
    +

    Delete message

    +

    + Below you see the message you're about to delete. If you click Yes, the message and its complete history log is deleted from the + database. This is an irreversable action. If you click No, nothing happens and you are transfered back to the thread containing + this message. +

    +
    +
    + + + + + + + + + + +
    + +
    + <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> +
    + + + + + + + + + +
    Message + + + + + + + + + + + +
    Posted on:  
    + +

    +

    +
      + Are you sure you want to delete this message?
    +

    +      + +


    +
    +
    +
    +
    + + + + diff --git a/GUI/DeleteMessage.aspx.cs b/GUI/DeleteMessage.aspx.cs new file mode 100644 index 0000000..c83952c --- /dev/null +++ b/GUI/DeleteMessage.aspx.cs @@ -0,0 +1,166 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// Code behind of DeleteMessage form. + /// + public partial class DeleteMessage : System.Web.UI.Page + { + private int _deleteMessageID; + private ThreadEntity _thread; + private bool _userMayDeleteMessages; + + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + _deleteMessageID=HnDGeneralUtils.TryConvertToInt(Request.QueryString["MessageID"]); + + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread==null) + + { + // not found, return to default page + Response.Redirect("default.aspx", true); + } + + // Check if the current user is allowed to delete the message. If not, don't continue. + _userMayDeleteMessages = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.EditDeleteOtherUsersMessages); + if(!_userMayDeleteMessages) + { + // is not allowed to delete the message + Response.Redirect("Messages.aspx?ThreadID=" + threadID, true); + } + + // check if the user can view this thread. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !_thread.IsSticky) + { + // can't view this thread, it isn't visible to the user + Response.Redirect("default.aspx", true); + } + + // check if the message is the first message in the thread. If so, delete isn't allowed. + if(ThreadGuiHelper.CheckIfMessageIsFirstInThread(threadID, _deleteMessageID)) + { + // is first in thread, don't proceed. Caller has fabricated the url manually. + Response.Redirect("default.aspx", true); + } + + // Get the message + MessageEntity message = MessageGuiHelper.GetMessage(_deleteMessageID); + + // User may delete current message. + if(!Page.IsPostBack) + { + if(message!=null) + { + // message is found. + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // Orphaned thread + Response.Redirect("default.aspx", true); + } + lblForumName_Header.Text = forum.ForumName; + lblMessageBody.Text = message.MessageTextAsHTML; + lblPostingDate.Text = message.PostingDate.ToString(@"dd-MMM-yyyy HH:mm:ss"); + } + else + { + btnYes.Visible = false; + } + } + + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnYes.Click += new System.EventHandler(this.btnYes_Click); + this.btnNo.Click += new System.EventHandler(this.btnNo_Click); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnNo_Click(object sender, System.EventArgs e) + { + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID, true); + } + + private void btnYes_Click(object sender, System.EventArgs e) + { + if(_userMayDeleteMessages) + { + bool result = MessageManager.DeleteMessage(_deleteMessageID); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID, true); + } + } + + #region Class Property Declarations + /// + /// Gets the thread subject. + /// + /// The thread subject. + protected string ThreadSubject + { + get + { + string toReturn = string.Empty; + if(_thread != null) + { + toReturn = _thread.Subject; + } + return toReturn; + } + } + #endregion + } +} + diff --git a/GUI/DeleteThread.aspx b/GUI/DeleteThread.aspx new file mode 100644 index 0000000..6a379d6 --- /dev/null +++ b/GUI/DeleteThread.aspx @@ -0,0 +1,70 @@ +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Page language="c#" CodeFile="DeleteThread.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.DeleteThread" %> + + + + HnD::Delete a thread + + + +
    + + +
    +

    + + + + +
    +

    Delete a thread

    +

    + Below you see the thread you're about to delete. If you click Delete, the thread, all its messages and all the complete history log + for all the messages in this thread are deleted from the database. This is an irreversable action. If you click Keep, + nothing happens and you are transfered back to the thread. +

    +
    +
    + + + + + + + + + + +
    + Thread marked for deletion +
    + + + + + + + + + + + +
      +
    + Forum:
    + Thread:
    +
    +

    +
    +
    +       +
    +
    +
     
    +
    +
    + + + + diff --git a/GUI/DeleteThread.aspx.cs b/GUI/DeleteThread.aspx.cs new file mode 100644 index 0000000..56bb873 --- /dev/null +++ b/GUI/DeleteThread.aspx.cs @@ -0,0 +1,132 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file for the DeleteThread form. + /// + public partial class DeleteThread : System.Web.UI.Page + { + #region Class Member Declarations + private ThreadEntity _thread; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread == null) + { + // not found, return to default page + Response.Redirect("default.aspx", true); + } + + // Check credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx"); + } + + bool userMayDeleteThread = SessionAdapter.HasSystemActionRight(ActionRights.SystemWideThreadManagement); + if(!userMayDeleteThread) + { + // doesn't have the right to delete a thread. redirect + Response.Redirect("Messages.aspx?ThreadID=" + threadID, true); + } + + // check if the user can view this thread. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !_thread.IsSticky) + { + // can't view this thread, it isn't visible to the user + Response.Redirect("default.aspx", true); + } + + if(!Page.IsPostBack) + { + // fill the page's content + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // Orphaned thread + Response.Redirect("default.aspx", true); + } + lblForumName.Text = forum.ForumName; + lblThreadSubject.Text = HttpUtility.HtmlEncode(_thread.Subject); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnDelete.ServerClick += new System.EventHandler(this.btnDelete_ServerClick); + this.btnKeep.ServerClick += new System.EventHandler(this.btnKeep_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnDelete_ServerClick(object sender, System.EventArgs e) + { + // delete the thread + bool result = ThreadManager.DeleteThread(_thread.ThreadID); + // done + Response.Redirect("Threads.aspx?ForumID=" + _thread.ForumID, true); + } + + private void btnKeep_ServerClick(object sender, System.EventArgs e) + { + // do nothing + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID, true); + } + } +} diff --git a/GUI/EditMemoForThread.aspx b/GUI/EditMemoForThread.aspx new file mode 100644 index 0000000..c6a888b --- /dev/null +++ b/GUI/EditMemoForThread.aspx @@ -0,0 +1,31 @@ +<%@ Register TagPrefix="HnD" TagName="MessageEditor" Src="MessageEditor.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Page language="c#" CodeFile="EditMemoForThread.aspx.cs" AutoEventWireup="false" ValidateRequest="false" Inherits="SD.HnD.GUI.EditMemoForThread" %> + + + + HnD::Edit Memo information for thread thread: <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> + + + +
    + + + + + +
    +
    + You are here: Home > > + > + > Edit memo +

    +
    + + +
    + + + + diff --git a/GUI/EditMemoForThread.aspx.cs b/GUI/EditMemoForThread.aspx.cs new file mode 100644 index 0000000..6e9d637 --- /dev/null +++ b/GUI/EditMemoForThread.aspx.cs @@ -0,0 +1,171 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.Utility; + +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// Edit memo for thread. + /// + public partial class EditMemoForThread : System.Web.UI.Page + { + #region Class Member Declarations + private int _startAtMessage; + private ThreadEntity _thread; + #endregion + + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread==null) + { + // not found, return to default page + Response.Redirect("default.aspx", true); + } + + _startAtMessage = HnDGeneralUtils.TryConvertToInt(Request.QueryString["StartAtMessage"]); + + // Check credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx", true); + } + + // check if the user can view this thread. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !_thread.IsSticky) + { + // can't view this thread, it isn't visible to the user + Response.Redirect("default.aspx", true); + } + + // Check if the current user is allowed to edit the memo + if(!SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.EditThreadMemo)) + { + // is not allowed to edit the memo + Response.Redirect("Messages.aspx?ThreadID=" + threadID, true); + } + + // User may edit memo, proceed + if(!Page.IsPostBack) + { + // fill the page's content + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // Orphaned thread + Response.Redirect("default.aspx", true); + } + lnkThreads.Text = HttpUtility.HtmlEncode(forum.ForumName); + lnkThreads.NavigateUrl += "?ForumID=" + _thread.ForumID; + meMessageEditor.ForumName = forum.ForumName; + meMessageEditor.ThreadSubject = "Memo for thread: " + HttpUtility.HtmlEncode(_thread.Subject); + lblSectionName.Text = CacheManager.GetSectionName(forum.SectionID); + lnkMessages.NavigateUrl+=threadID; + lnkMessages.Text = HttpUtility.HtmlEncode(_thread.Subject); + + string memoText = _thread.Memo; + memoText += string.Format("{2}[b]-----------------------------------------------------------------{2}{1} [color value=\"0000AA\"]{0}[/color] wrote:[/b] ", SessionAdapter.GetUserNickName(), DateTime.Now.ToString(@"dd-MMM-yyyy HH:mm:ss"), Environment.NewLine); + meMessageEditor.OriginalMessageText=memoText; + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + protected void PostMessageHandler(object sender, System.EventArgs e) + { + ThreadManager.UpdateMemo(_thread.ThreadID, meMessageEditor.MessageText); + if(SessionAdapter.CheckIfNeedsAuditing(AuditActions.AuditEditMemo)) + { + SecurityManager.AuditEditMemo(SessionAdapter.GetUserID(), _thread.ThreadID); + } + + // all ok, redirect to thread list + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startAtMessage, false); + } + + protected void CancelActionHandler(object sender, System.EventArgs e) + { + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startAtMessage, true); + } + + #region Class Property Declarations + /// + /// Gets the thread subject. + /// + /// The thread subject. + protected string ThreadSubject + { + get + { + string toReturn = string.Empty; + if(_thread != null) + { + toReturn = _thread.Subject; + } + return toReturn; + } + } + #endregion + } +} diff --git a/GUI/EditMessage.aspx b/GUI/EditMessage.aspx new file mode 100644 index 0000000..c9bb114 --- /dev/null +++ b/GUI/EditMessage.aspx @@ -0,0 +1,33 @@ +<%@ Page language="c#" CodeFile="EditMessage.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.EditMessage" ValidateRequest="false"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="MessageEditor" Src="MessageEditor.ascx"%> + + + + HnD::Edit a message in thread: <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> + + + + + +
    + + + + + +
    +
    + You are here: Home > > + > + > Edit message +

    +
    + + +
    + + + + diff --git a/GUI/EditMessage.aspx.cs b/GUI/EditMessage.aspx.cs new file mode 100644 index 0000000..c4d88fe --- /dev/null +++ b/GUI/EditMessage.aspx.cs @@ -0,0 +1,206 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// Edit message editor class + /// + public partial class EditMessage : System.Web.UI.Page + { + #region Class Member Declarations + private int _editMessageID, _startAtMessageIndex; + private MessageEntity _message; + private ThreadEntity _thread; + #endregion + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + _editMessageID=HnDGeneralUtils.TryConvertToInt(Request.QueryString["MessageID"]); + _message = MessageGuiHelper.GetMessage(_editMessageID); + if(_message==null) + { + // not found + Response.Redirect("default.aspx"); + } + + // We could have used Lazy loading here, but for the sake of separation, we use the BL method. + _thread = ThreadGuiHelper.GetThread(_message.ThreadID); + if(_thread==null) + { + // not found. Orphaned message. + Response.Redirect("default.aspx"); + } + + // Check credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx", true); + } + + // Check if the current user is allowed to edit the message. + bool userMayEditMessages=false; + if(!_thread.IsClosed) + { + if(_thread.IsSticky) + { + userMayEditMessages = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAndEditMessageInSticky); + } + else + { + userMayEditMessages = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAndEditMessage); + } + } + + // User has the right to generally edit messages. Check if the user has the right to edit other peoples messages + // and if not, if the user is the poster of this message. If not, no can do. + if(!SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.EditDeleteOtherUsersMessages)) + { + // cannot edit other people's messages. Check if this message is posted by the current user. + if(_message.PostedByUserID != SessionAdapter.GetUserID()) + { + // not allowed + userMayEditMessages=false; + } + } + if(!userMayEditMessages) + { + // is not allowed to edit the message + Response.Redirect("Messages.aspx?ThreadID=" + _message.ThreadID, true); + } + + // use BL class. We could have used Lazy loading, though for the sake of separation, we'll call into the BL class. + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // orphaned thread + Response.Redirect("default.aspx"); + } + + // check if the user can view the thread the message is in. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers)) + { + // can't edit this message, it's in a thread which isn't visible to the user + Response.Redirect("default.aspx", true); + } + + _startAtMessageIndex = HnDGeneralUtils.TryConvertToInt(Request.QueryString["StartAtMessage"]); + + // User may edit current message. + if(!Page.IsPostBack) + { + // fill the page's content + lnkThreads.Text = HttpUtility.HtmlEncode(forum.ForumName); + lnkThreads.NavigateUrl += "?ForumID=" + _thread.ForumID; + meMessageEditor.ForumName = forum.ForumName; + meMessageEditor.ThreadSubject = _thread.Subject; + lblSectionName.Text = CacheManager.GetSectionName(forum.SectionID); + lnkMessages.NavigateUrl+=_message.ThreadID; + lnkMessages.Text = HttpUtility.HtmlEncode(_thread.Subject); + + meMessageEditor.OriginalMessageText = _message.MessageText; + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + + protected void PostMessageHandler(object sender, System.EventArgs e) + { + int userID = SessionAdapter.GetUserID(); + bool result = MessageManager.UpdateEditedMessage(userID, _editMessageID, meMessageEditor.MessageText, meMessageEditor.MessageTextHTML, Request.UserHostAddress, meMessageEditor.MessageTextXML); + + if(SessionAdapter.CheckIfNeedsAuditing(AuditActions.AuditAlteredMessage)) + { + SecurityManager.AuditAlteredMessage(userID, _editMessageID); + } + + // all ok, redirect to thread list + int startAtMessageID = ThreadGuiHelper.GetStartAtMessageForGivenMessageAndThread(_thread.ThreadID, _editMessageID, SessionAdapter.GetUserDefaultNumberOfMessagesPerPage()); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + startAtMessageID + "&#" + _editMessageID, false); + } + + protected void CancelActionHandler(object sender, System.EventArgs e) + { + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startAtMessageIndex, true); + } + + + #region Class Property Declarations + /// + /// Gets the thread subject. + /// + /// The thread subject. + protected string ThreadSubject + { + get + { + if(_thread != null) + { + return _thread.Subject; + } + else + { + return string.Empty; + } + } + } + + #endregion + } +} diff --git a/GUI/EditProfile.aspx b/GUI/EditProfile.aspx new file mode 100644 index 0000000..bc477ef --- /dev/null +++ b/GUI/EditProfile.aspx @@ -0,0 +1,160 @@ +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Page language="c#" CodeFile="EditProfile.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.EditProfile" ValidateRequest="false" %> + + + + HnD::Edit your profile + + + + + + + + +
    +
    +
    + + + + +
    + Edit your profile. +

    Below you can change your information currently known by the forumsystem. If you want to change your password, + enter a value in the two password boxes, otherwise leave these boxes blank. When no password is filled in, your + current password is kept. +

    +

    + No information will be disclosed to other parties than the forumsystem itself. You decide which information you + want to enter in the non-mandatory fields. The email-address you enter is used to send you a new password if you + request it from the system again in the case you forgot your password. It can be made hidden for visitors of the forums. +

    +
    +
    + + + + +
    + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Your profile
    Registration information. Fields marked with a '*' are mandatory.
    Nickname + +
    New password + +
    New Password
    + For confirmation +
    + + +
    Emailaddress * +   + + +

    Personal information, which should tell something about you.
    User icon URL
    + (Only 60x60 .jpg and .gif are accepted) +
    + http://
    + +
    Date of birth
    + Format: mm/dd/yyyy
    + + +
    Occupation
    Location
    + e.g.: city, country
    Websitehttp://
    + +
    Signature
    + You can use several UBB Tags in your signature. Maximum length is 250 characters.

    Preferences.
    Email address is hidden
    Notify me of thread replies
    + Overridable per-thread +
    Messages per page
    + Takes effect the next time you login/visit the site. +
    + +
      +
    + +
    +
    +
    +
    + + + + diff --git a/GUI/EditProfile.aspx.cs b/GUI/EditProfile.aspx.cs new file mode 100644 index 0000000..9d276f2 --- /dev/null +++ b/GUI/EditProfile.aspx.cs @@ -0,0 +1,180 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Globalization; + +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// General class for profile editing + /// + public partial class EditProfile : System.Web.UI.Page + { + private int _userID; + + private void Page_Load(object sender, System.EventArgs e) + { + // use the UserID from the session, so it's impossible to edit another user. + _userID = SessionAdapter.GetUserID(); + if(_userID <= 0) + { + // anonymous + Response.Redirect("default.aspx"); + } + + if(!Page.IsPostBack) + { + + // load the user entity from the db. + UserEntity user = UserGuiHelper.GetUser(_userID); + + // fill in the form with data + lblNickname.Text = user.NickName; + tbxEmailAddress.Value = user.EmailAddress; + tbxIconURL.Value = user.IconURL; + if(user.DateOfBirth.HasValue) + { + DateTime dateOfBirth = user.DateOfBirth.Value; + tbxDateOfBirth.Value = dateOfBirth.Month.ToString("0#") + "/" + dateOfBirth.Day.ToString("0#") + "/" + dateOfBirth.Year.ToString("####"); + } + tbxOccupation.Value = user.Occupation; + tbxLocation.Value = user.Location; + tbxWebsite.Value = user.Website; + tbxSignature.Value = user.Signature; + if(user.EmailAddressIsPublic.HasValue) + { + chkEmailAddressIsHidden.Checked = !user.EmailAddressIsPublic.Value; + } + else + { + chkEmailAddressIsHidden.Checked = false; + } + + chkAutoSubscribeToThread.Checked = user.AutoSubscribeToThread; + tbxDefaultNumberOfMessagesPerPage.Value = user.DefaultNumberOfMessagesPerPage.ToString(); + } + } + + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnUpdate.ServerClick += new System.EventHandler(this.btnUpdate_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnUpdate_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + // user has filled in the right values, update the user's data. + string nickName = string.Empty; + DateTime? dateOfBirth = null; + string emailAddress = string.Empty; + bool emailAddressIsPublic = false; + string iconURL = string.Empty; + string ipNumber = string.Empty; + string location = string.Empty; + string occupation = string.Empty; + string password = string.Empty; + string signature = string.Empty; + string website = string.Empty; + bool autoSubscribeThreads = true; + short defaultMessagesPerPage = 10; + + if(tbxPassword1.Value.Length > 0) + { + password = tbxPassword1.Value; + } + + emailAddress = tbxEmailAddress.Value; + iconURL = tbxIconURL.Value; + + if(tbxDateOfBirth.Value.Length > 0) + { + try + { + dateOfBirth = System.DateTime.Parse(tbxDateOfBirth.Value, CultureInfo.InvariantCulture.DateTimeFormat); + } + catch(FormatException) + { + // format exception, date invalid, ignore, will resolve to default. + } + } + + emailAddressIsPublic = !chkEmailAddressIsHidden.Checked; + location = tbxLocation.Value; + occupation = tbxOccupation.Value; + signature = tbxSignature.Value; + website = tbxWebsite.Value; + + //Preferences + autoSubscribeThreads = chkAutoSubscribeToThread.Checked; + if (tbxDefaultNumberOfMessagesPerPage.Value.Length > 0) + { + defaultMessagesPerPage = HnDGeneralUtils.TryConvertToShort(tbxDefaultNumberOfMessagesPerPage.Value); + } + + bool result = UserManager.UpdateUserProfile(SessionAdapter.GetUserID(), dateOfBirth, emailAddress, emailAddressIsPublic, iconURL, location, occupation, password, + signature, website, SessionAdapter.GetUserTitleID(), ApplicationAdapter.GetParserData(), autoSubscribeThreads, defaultMessagesPerPage); + + if(result) + { + // get user back and update session object. + UserEntity user = UserGuiHelper.GetUser(SessionAdapter.GetUserID()); + if(user != null) + { + SessionAdapter.AddUserObject(user); + } + // all ok + Response.Redirect("EditProfileSuccessful.aspx",true); + } + } + } + } +} diff --git a/GUI/EditProfileSuccessful.aspx b/GUI/EditProfileSuccessful.aspx new file mode 100644 index 0000000..b772748 --- /dev/null +++ b/GUI/EditProfileSuccessful.aspx @@ -0,0 +1,32 @@ +<%@ Page language="c#" CodeFile="EditProfileSuccessful.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.EditProfileSuccessful" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> + + + + HnD::Edit profile Successful + + + + + +
    +

    + + + + +
    +

    Profile has been updated successfully!

    + Your profile has been updated successfully. You can now close this window. +

    +
    + Close window +
    +
    +
    +
    + + + + diff --git a/GUI/EditProfileSuccessful.aspx.cs b/GUI/EditProfileSuccessful.aspx.cs new file mode 100644 index 0000000..4eb7354 --- /dev/null +++ b/GUI/EditProfileSuccessful.aspx.cs @@ -0,0 +1,63 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI +{ + /// + /// Empty code behind of small form which reports a success of profile editing. + /// + public partial class EditProfileSuccessful : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // Put user code to initialize the page here + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/GUI/EditThreadProperties.aspx b/GUI/EditThreadProperties.aspx new file mode 100644 index 0000000..8275b19 --- /dev/null +++ b/GUI/EditThreadProperties.aspx @@ -0,0 +1,76 @@ +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Page language="c#" CodeFile="EditThreadProperties.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.EditThreadProperties" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> + + + + HnD::Edit thread properties of thread: <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> + + + + + +
    + + +
    +
    + + + + +
    + Edit Thread Properties +

    + Below you can change the properties of the thread <%=HttpUtility.HtmlEncode(base.ThreadSubject)%>. + When you enable the Closed checkbox, the thread is closed but there will be no close message at the end + of the thread. If you want that, use the close thread option in the message view. +

    +
    +
    + + + + +
    + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Thread Properties of thread: <%=HttpUtility.HtmlEncode(base.ThreadSubject)%>
    Fields marked with a '*' are mandatory.
    Subject * + + +
    Is closed
    Is pinned / sticky
      +
    +    + +
    +
    +
    +
    + + + + diff --git a/GUI/EditThreadProperties.aspx.cs b/GUI/EditThreadProperties.aspx.cs new file mode 100644 index 0000000..9f5af9e --- /dev/null +++ b/GUI/EditThreadProperties.aspx.cs @@ -0,0 +1,133 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// Code behind for EditThreadProperties form, which allows an admin to alter properties of a thread. + /// + public partial class EditThreadProperties : System.Web.UI.Page + { + #region Class Member Declarations + private ThreadEntity _thread; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread == null) + { + // not found, return to default page + Response.Redirect("default.aspx", true); + } + + // Check access credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + bool userMayDoThreadManagement = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ForumSpecificThreadManagement)|| + SessionAdapter.HasSystemActionRight(ActionRights.SystemWideThreadManagement); + if(!userHasAccess || !userMayDoThreadManagement) + { + // doesn't have access to this forum or may not alter the thread's properties. redirect + Response.Redirect("default.aspx"); + } + + if(!Page.IsPostBack) + { + chkIsClosed.Checked = _thread.IsClosed; + chkIsSticky.Checked = _thread.IsSticky; + tbxSubject.Value = _thread.Subject; + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnUpdate.ServerClick += new System.EventHandler(this.btnUpdate_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnCancel_ServerClick(object sender, System.EventArgs e) + { + // do nothing + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID); + } + + private void btnUpdate_ServerClick(object sender, System.EventArgs e) + { + // user wants the data to be updated. + bool result = ThreadManager.ModifyThreadProperties(_thread.ThreadID, tbxSubject.Value, chkIsSticky.Checked, chkIsClosed.Checked); + + // ignore returnvalue for now + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID); + } + + + #region Class Property Declarations + /// + /// Gets the thread subject. + /// + /// The thread subject. + protected string ThreadSubject + { + get + { + string toReturn = string.Empty; + if(_thread != null) + { + toReturn = _thread.Subject; + } + return toReturn; + } + } + #endregion + } +} diff --git a/GUI/FileStreamer.aspx b/GUI/FileStreamer.aspx new file mode 100644 index 0000000..9d5f951 --- /dev/null +++ b/GUI/FileStreamer.aspx @@ -0,0 +1 @@ +<%@ Page Language="C#" Buffer="false" AutoEventWireup="true" CodeFile="FileStreamer.aspx.cs" Inherits="SD.HnD.GUI.FileStreamer" %> \ No newline at end of file diff --git a/GUI/FileStreamer.aspx.cs b/GUI/FileStreamer.aspx.cs new file mode 100644 index 0000000..5262838 --- /dev/null +++ b/GUI/FileStreamer.aspx.cs @@ -0,0 +1,107 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.BL; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file of the filestreamer form, which is actually empty, and is used to send an attachment to the requesting browser. + /// + public partial class FileStreamer : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + int attachmentID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["AttachmentID"]); + + MessageEntity relatedMessage = MessageGuiHelper.GetMessageWithAttachmentLogic(attachmentID); + if(relatedMessage == null) + { + // not found + Response.Redirect("default.aspx", true); + } + + // thread has been loaded into the related message object as well. This is needed for the forum access right check + if(!SessionAdapter.CanPerformForumActionRight(relatedMessage.Thread.ForumID, ActionRights.AccessForum)) + { + // user can't access this forum + Response.Redirect("default.aspx", true); + } + + // Check if the thread is sticky, or that the user can see normal threads started + // by others. If not, the user isn't allowed to view the thread the message is in, and therefore is denied access. + if((relatedMessage.Thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(relatedMessage.Thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !relatedMessage.Thread.IsSticky) + { + // user can't view the thread the message is in, because: + // - the thread isn't sticky + // AND + // - the thread isn't posted by the calling user and the user doesn't have the right to view normal threads started by others + Response.Redirect("default.aspx", true); + } + + AttachmentEntity toStream = MessageGuiHelper.GetAttachment(attachmentID); + if(toStream == null) + { + // not found + Response.Redirect("default.aspx", true); + } + + if(!toStream.Approved && !SessionAdapter.CanPerformForumActionRight(relatedMessage.Thread.ForumID, ActionRights.ApproveAttachment)) + { + // the attachment hasn't been approved yet, and the caller isn't entitled to approve attachments, so deny. + // approval of attachments requires to be able to load the attachment without the attachment being approved + Response.Redirect("default.aspx", true); + } + + // all set, load stream the attachment data to the browser + // create header + Response.ClearHeaders(); + Response.ClearContent(); + Response.AddHeader("Content-Type", "application/unknown"); + Response.AddHeader("Content-length", toStream.Filecontents.Length.ToString()); + Response.AddHeader("Content-Disposition", "attachment; filename=" + toStream.Filename.Replace(" ", "_")); + Response.AddHeader("Content-Transfer-Encoding", "Binary"); + // stream the data + Response.BinaryWrite(toStream.Filecontents); + Response.Flush(); + Response.End(); + } + + + private void Page_PreInit(object sender, EventArgs e) + { + // switch off theming as the EnableTheming option on the page level doesn't work + Page.Theme = ""; + } + } +} \ No newline at end of file diff --git a/GUI/Footer.ascx b/GUI/Footer.ascx new file mode 100644 index 0000000..1b1163f --- /dev/null +++ b/GUI/Footer.ascx @@ -0,0 +1,14 @@ +<%@ Control Language="c#" AutoEventWireup="false" CodeFile="Footer.ascx.cs" Inherits="SD.HnD.GUI.Footer" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> +<%@ Import namespace="SD.HnD.BL" %> + + + + +
    +
    + Powered by HnD ©2002-2007 Solutions Design
    + HnD uses LLBLGen Pro
    +
    + Version: <%=Globals.Version%>.<%=Globals.Build%> <%=Globals.ReleaseType%>. +

    +
    diff --git a/GUI/Footer.ascx.cs b/GUI/Footer.ascx.cs new file mode 100644 index 0000000..e6b944b --- /dev/null +++ b/GUI/Footer.ascx.cs @@ -0,0 +1,59 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +namespace SD.HnD.GUI +{ + using System; + using System.Data; + using System.Drawing; + using System.Web; + using System.Web.UI.WebControls; + using System.Web.UI.HtmlControls; + + /// + /// Empty code behind of footer control. + /// + public abstract partial class Footer : System.Web.UI.UserControl + { + + private void Page_Load(object sender, System.EventArgs e) + { + // Put user code to initialize the page here + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/GUI/Global.asax b/GUI/Global.asax new file mode 100644 index 0000000..2ecc23d --- /dev/null +++ b/GUI/Global.asax @@ -0,0 +1,206 @@ +<%@ Application Language="C#" %> +<%@ Import Namespace="SD.HnD.BL" %> +<%@ Import Namespace="System.Data" %> +<%@ Import Namespace="SD.HnD.DAL.EntityClasses" %> +<%@ Import Namespace="SD.HnD.DAL.CollectionClasses" %> +<%@ Import Namespace="SD.HnD.GUI" %> + + diff --git a/GUI/GotoMessage.aspx b/GUI/GotoMessage.aspx new file mode 100644 index 0000000..eab90e0 --- /dev/null +++ b/GUI/GotoMessage.aspx @@ -0,0 +1 @@ +<%@ Page language="c#" CodeFile="GotoMessage.aspx.cs" Inherits="SD.HnD.GUI.GotoMessage" AutoEventWireup="true" EnableTheming="false" %> \ No newline at end of file diff --git a/GUI/GotoMessage.aspx.cs b/GUI/GotoMessage.aspx.cs new file mode 100644 index 0000000..3c7c101 --- /dev/null +++ b/GUI/GotoMessage.aspx.cs @@ -0,0 +1,56 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// Code behind for GotoMessage form, which redirects a user to the right page in a thread based on the messageID to view. + /// It's a small utility form which allows redirection to a message without first calculating on which page it is located. + /// + public partial class GotoMessage : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + int messageID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["MessageID"]); + int startAtMessage = ThreadGuiHelper.GetStartAtMessageForGivenMessageAndThread(threadID, messageID, SessionAdapter.GetUserDefaultNumberOfMessagesPerPage()); + Response.Redirect("Messages.aspx?ThreadID=" + threadID + "&StartAtMessage=" + startAtMessage + "&#" + messageID, true); + } + + private void Page_PreInit(object sender, EventArgs e) + { + // switch off theming as the EnableTheming option on the page level doesn't work + Page.Theme = ""; + } + } +} diff --git a/GUI/Header.ascx b/GUI/Header.ascx new file mode 100644 index 0000000..3c6af36 --- /dev/null +++ b/GUI/Header.ascx @@ -0,0 +1,54 @@ +<%@ Control Language="c#" AutoEventWireup="true" CodeFile="Header.ascx.cs" Inherits="SD.HnD.GUI.Header" %> + + + + + + + + + + + + +
    + + +
    + Home
    + Help
    + + Register
    + Log in
    +
    + + Log out
    + Profile
    +
    +
    + Search
    +
    +
     
    +    + Active Threads + +  |  + My Bookmarks +  |  + My Threads + + +  |  + Administrate + + +  |  + Approve Attachments + + +  |  + Support Queues + +  
    + + diff --git a/GUI/Header.ascx.cs b/GUI/Header.ascx.cs new file mode 100644 index 0000000..e78d586 --- /dev/null +++ b/GUI/Header.ascx.cs @@ -0,0 +1,54 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +namespace SD.HnD.GUI +{ + using System; + using System.Data; + using System.Drawing; + using System.Web; + using System.Web.UI.WebControls; + using System.Web.UI.HtmlControls; + using SD.HnD.BL; + using System.Collections.Generic; + + /// + /// code-behind of Header control + /// + public partial class Header : System.Web.UI.UserControl + { + private void Page_Load(object sender, System.EventArgs e) + { + if(!Page.IsPostBack) + { + // Check some credentials/properties and decide then which controls to show. + // enable/disable the controls for logged in visitors. + phNotLoggedIn.Visible = !Request.IsAuthenticated; + phLoggedIn.Visible = Request.IsAuthenticated; + phLoggedInBottom.Visible = Request.IsAuthenticated; + phAdministrate.Visible = SessionAdapter.CanAdministrate(); + phSupportQueues.Visible = SessionAdapter.HasSystemActionRight(ActionRights.QueueContentManagement); + + // check if the user has the action right to approve attachments on some forum. If so, show the menu item + List forumsWithApprovalRight = SessionAdapter.GetForumsWithActionRight(ActionRights.ApproveAttachment); + phAttachmentApproval.Visible = ((forumsWithApprovalRight != null) && (forumsWithApprovalRight.Count > 0)); + } + } + } +} diff --git a/GUI/HeaderRestrictedMenu.ascx b/GUI/HeaderRestrictedMenu.ascx new file mode 100644 index 0000000..d916eed --- /dev/null +++ b/GUI/HeaderRestrictedMenu.ascx @@ -0,0 +1,24 @@ +<%@ Control Language="c#" AutoEventWireup="true" CodeFile="HeaderRestrictedMenu.ascx.cs" Inherits="SD.HnD.GUI.HeaderRestrictedMenu" %> + + + + + + + + + + + + +
    + + +
    + Home
    + Help
    +
    +
     
    +  
    + + diff --git a/GUI/HeaderRestrictedMenu.ascx.cs b/GUI/HeaderRestrictedMenu.ascx.cs new file mode 100644 index 0000000..368755a --- /dev/null +++ b/GUI/HeaderRestrictedMenu.ascx.cs @@ -0,0 +1,40 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +namespace SD.HnD.GUI +{ + using System; + using System.Data; + using System.Drawing; + using System.Web; + using System.Web.UI.WebControls; + using System.Web.UI.HtmlControls; + using SD.HnD.BL; + using System.Collections.Generic; + + /// + /// code-behind of Header control + /// + public partial class HeaderRestrictedMenu : System.Web.UI.UserControl + { + private void Page_Load(object sender, System.EventArgs e) + { + } + } +} diff --git a/GUI/Help.aspx b/GUI/Help.aspx new file mode 100644 index 0000000..b646f26 --- /dev/null +++ b/GUI/Help.aspx @@ -0,0 +1,333 @@ +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> +<%@ Page language="c#" CodeFile="Help.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Help" %> + + + + HnD::Manual + + + + + +
    +
    + + + + +
    +
    +

    Manual

    +
    + Contents
    + The following sections are available:
    + +
    + + UBB Tags
    + When adding or editing messages, you can insert special tags to make your texts more alive. Also in your + signature you can use several of the UBB tags mentioned below, to create special formatting of the text or to include + a link for example. Tags marked with a '*' in the column 'Sig' are also available for usage in your signature. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TagSig
    + Tag: [br]
    + Inserts a hard CRLF into the text. Equivalent of HTML's <br>

    +
    *
    + Tag: [b]text[/b]
    + Makes text become bold

    + Example:
    + [b]this is a test[/b] will result in: this is a test +
    *
    + Tag: [i]text[/i]
    + Makes text become italic

    + Example:
    + [i]this is a test[/i] will result in: this is a test +
    *
    + Tag: [s]text[/s]
    + Makes text become striked through

    + Example:
    + [s]this is a test[/s] will result in: this is a test +
    *
    + Tag: [u]text[/u]
    + Makes text become underlined

    + Example:
    + [u]this is a test[/u] will result in: this is a test +
    *
    + Tag: [img]ImageURI[/img]
    + Will show the image located by ImageURI in the message. ImageURI has to end on '.gif', '.jpg' or '.png'. + ImageURI's are matched using the following Regular Expression:
    + (http://www.|http://)([\w-]+\.)+[\w-]+(/[\w-./?%&+,#;~=]*)?/[\w-]+\.(jpg|gif|png) +

    + Example:
    + [img]http://www.llblgen.com/pics/llblgen.gif[/img]. will result in:
    + +
     
    + Tag: [img alt="Alt text"]ImageURI[/img]
    + As '[img]ImageURI[/img]', but now also the alt attribute of the image is specified.

    + Example:
    + [img alt="LLBLGen Pro logo"]http://www.llblgen.com/pics/llblgen.gif[/img] will result in:
    + LLBLGen Pro Logo +
     
    + Tag: [url]URI[/url]
    + Will result in a clickable link of URI, with the description the same as the URI itself. The + link will open in a new window. URI's are matched using the following Regular Expression:
    + (http://www.|http://|www.)([\w-]+\.)+[\w-]+(/[\w-./?%&~=]*)? +

    + Example:
    + [url]http://www.llblgen.com/HnD[/url] will result in:
    + http://www.llblgen.com/Hnd +
    *
    + Tag: [url description="Link description"]URI[/url]
    + Will result in a clickable link of URI, with the description set to the text specified as the description. The + link will open in a new window.

    + Example:
    + [url description="HnD homepage"]http://www.llblgen.com/HnD[/url] will result in:
    + HnD homepage +
    *
    + Tag: [quote]text[/quote]
    + text will show up as a quoted block of text in the message. +

    + Example:
    + [quote]This is a test[/quote] will result in:
    + + + + + + + +
    Quote:
    This is a test
    +
     
    + Tag: [quote nick="NickName"]text[/quote]
    + text will show up as a quoted block of text in the message, and will add a line with the nickname provided so readers + can see that person actually wrote the quoted text. +

    + Example:
    + [quote nick="Admin"]This is a test[/quote] will result in:
    + + + + + + + +
    Admin wrote:
    This is a test
    +
     
    + Tag: [code]text[/code]
    + text will show up as if it was a piece of code posted. It will keep its formatting, thus tabs and hard CRLF's are kept. The + font used is a proportional font, and wrapping will occur when a line is too big. +

    + Example:
    + [code]
    + void main()
    + {
    +     printf("this is a test");
    + }
    + [/code]

    + will result in:
    + + + + + + + +
    Code:
    + void main()
    + {
    +     printf("this is a test");
    + }
    +
    +
     
    + Tag: [offtopic]text[/offtopic]
    + Makes text become displayed smaller and in a different color so it is separated from the main text.

    + Example:
    + [offtopic]this is a test[/offtopic] will result in: +

    + Offtopic:
    this is a test
    +
     
    + Tag: [list][*]item1[/*]...[/list]
    + Will format the list of items which are formatted between [*] and [/*] into a list with dots (An 'UL') list. + You can use formatting inside an item. +

    + Example:
    + [list]
    + [*]This is item 1[/*]
    + [*]This is item 2[/*]
    + [/list]

    + will result in: +
      +
    • This is item 1
    • +
    • This is item 2
    • +
    +
     
    + Tag: [list type="UL|OL"][*]item1[/*]...[/list]
    + Will format the list of items which are formatted between [*] and [/*] into a list with dots when type = "UL", or + in a list of numbers when the type = "OL". You can use formatting inside an item. +

    + Example:
    + [list type="OL"]
    + [*]This is item 1[/*]
    + [*]This is item 2[/*]
    + [/list]

    + will result in: +
      +
    1. This is item 1
    2. +
    3. This is item 2
    4. +
    +
     
    + Tag: [size value='1|2|3|4|5|6]text[/size]
    + Makes text become displayed in the size specified, 1 being very small, 6 being very large. +

    + Example:
    + [size value='5']this is a test[/size] will result in: +

    + this is a test +
     
    + Tag: [color value="Hexvalue"]text[/color]
    + Makes text become displayed in the color specified. The color has to be in hexadecimal: RRGGBB, without the '#'. +

    + Example:
    + [color value="FF0000"]this is a test[/color] will result in: +

    + this is a test +
    *
    + Tag: any valid email-address
    + The email-address is transformed into a clickable link which open a mail construction window using the default mail program. + Email-addresses are found using the following regular expression:
    + \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* +

    + Example:
    + My email address is: foobar@example.com

    + will result in: +

    + My email address is: foobar@example.com +
    *
    + Tag: any valid URL
    + The URL is transformed into a clickable link which opens a new browser window with the URL specified. Please do include 'http://' or + 'https://' because otherwise the link will end up as being a relative link to the forum and people will not be able to use it. + URL's are found using the following regular expression:
    + (http://www.|http://|https://www.|https://)([\w-]+\.)+[\w-]+(/[\w-./?%&+,~=#]*)? +

    + Example:
    + My homepage is: http://www.example.com/foldername

    + will result in: +

    + My homepage is: http://www.example.com/foldername +
    *
    + Tag: several smileys
    + HnD supports a nice collection of smileys to use in your texts to illustrate the meaning of the texts. These smileys are custom + designed for HnD so they fit in the layout. Use smileys with care, since misinterpretation of your texts based on the smileys can + occur plus some users might find all those happy faces annoying. You can't use smileys inside code-blocks.

    + The following collection is currently supported: +

    +
    +:D Laugh	:( Angry	:) Regular
    +;) Wink	8) Cool	:P Tongue
    +:? Confused	:o Shocked	:/ Dissapointed
    +;( Sad	:! Embarassed
    +				
    +
     
    +
    + All HTML code is transfered into XML readable code first and then back to readable text, which will result in having your HTML + code being readable as plain text and it won't get embedded into the resulting page. The same goes for script. All TAB characters are + transformed into 4 spaces, thus 4 &nbsp; characters. +

    +
    + Close window +
    +
    +
    +
    + + + + diff --git a/GUI/Help.aspx.cs b/GUI/Help.aspx.cs new file mode 100644 index 0000000..57e4b4a --- /dev/null +++ b/GUI/Help.aspx.cs @@ -0,0 +1,64 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI +{ + /// + /// Empty code behind of forum Help page. + /// + public partial class Help : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // Put user code to initialize the page here + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + } +} diff --git a/GUI/IPBanViewer.aspx b/GUI/IPBanViewer.aspx new file mode 100644 index 0000000..14617e7 --- /dev/null +++ b/GUI/IPBanViewer.aspx @@ -0,0 +1,55 @@ +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Page language="c#" CodeFile="IPBanViewer.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.IPBanViewer" %> +<%@ Import namespace="System.Data" %> + + + + HnD::IP-ban viewer. + + +
    + + + + + + + +
    +
    +

    You are banned.

    + Your IP-address, <%=Request.UserHostAddress%>, matches an IP-ban and therefor the forum system + will not let you access its contents. The IP-ban information which matches your IP-address + is stated below. If you are an innocent victim of the IP-ban mentioned below, you can + email to and explain what + happened and perhaps the IP-ban is lifted or changed (in the case of the ban of a range of + IP-addresses). +

    + The IP-ban is for this forum system only. +
    +
    + + + + + + + + + + + + + + + + +
    Matching IP-ban
    IP range + +
    IP ban set on
    Reason
    +
    +
    + + + + diff --git a/GUI/IPBanViewer.aspx.cs b/GUI/IPBanViewer.aspx.cs new file mode 100644 index 0000000..c167fe4 --- /dev/null +++ b/GUI/IPBanViewer.aspx.cs @@ -0,0 +1,86 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// General IP Ban viewer. This viewer enlists the first matching IP ban entity. This form is shown when the user is banned + /// via one or more IP Bans. + /// + public partial class IPBanViewer : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + if(!Page.IsPostBack) + { + string banComplainAddress = ApplicationAdapter.GetIPBanComplainEmailAddress(); + lnkBanComplaintEmailAddress.Text = banComplainAddress; + lnkBanComplaintEmailAddress.NavigateUrl += banComplainAddress; + + // get the set of IP-bans for the given IP address + string ipAddressUser = Request.UserHostAddress; + IPBanEntity matchingBan = SecurityGuiHelper.GetIPBanMatchingUserIPAddress(CacheManager.GetAllIPBans(), ipAddressUser); + + if(matchingBan!=null) + { + // has to match a ban + lblIPBanDate.Text = matchingBan.IPBanSetOn.ToString("dd-MMM-yyyy HH:mm:ss"); + lblIPBanRange.Text = string.Format("{0}.{1}.{2}.{3} / {4}", matchingBan.IPSegment1, matchingBan.IPSegment2, matchingBan.IPSegment3, + matchingBan.IPSegment4, matchingBan.Range); + lblIPBanReason.Text = matchingBan.Reason; + } + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + } +} diff --git a/GUI/IgnoredSearchWords.aspx b/GUI/IgnoredSearchWords.aspx new file mode 100644 index 0000000..7ba1d6d --- /dev/null +++ b/GUI/IgnoredSearchWords.aspx @@ -0,0 +1,39 @@ +<%@ Import namespace="System.Data" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Page language="c#" CodeFile="IgnoredSearchWords.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.IgnoredSearchWords" %> + + + + HnD::Ignored Search Words + + + + + +
    +
    +
    + + + + +
    +

    Ignored search words.

    + + + + + + + + +
    +
    + +
    +
    + + + + diff --git a/GUI/IgnoredSearchWords.aspx.cs b/GUI/IgnoredSearchWords.aspx.cs new file mode 100644 index 0000000..be464c6 --- /dev/null +++ b/GUI/IgnoredSearchWords.aspx.cs @@ -0,0 +1,100 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Text; + +namespace SD.HnD.GUI +{ + /// + /// Code behind for the ignored searchwords page. + /// + public partial class IgnoredSearchWords : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + if(!Page.IsPostBack) + { + Hashtable noiseWords = ApplicationAdapter.GetNoiseWords(); + ArrayList sortedWords = new ArrayList(noiseWords.Keys); + sortedWords.Sort(); + StringBuilder[] wordLists = new StringBuilder[5]; + for (int i = 0; i < 5; i++) + { + wordLists[i] = new StringBuilder(); + } + + int numWords = sortedWords.Count; + int colSize = numWords/5; + + for (int i = 0; i < colSize; i++) + { + wordLists[0].AppendFormat("{0}
    ", sortedWords[i]); + wordLists[1].AppendFormat("{0}
    ", sortedWords[i+colSize]); + wordLists[2].AppendFormat("{0}
    ", sortedWords[i+(colSize*2)]); + wordLists[3].AppendFormat("{0}
    ", sortedWords[i+(colSize*3)]); + wordLists[4].AppendFormat("{0}
    ", sortedWords[i+(colSize*4)]); + } + + int rest = numWords - (5*colSize); // at least 0, at most 4 + + for (int i = 1; i <= rest; i++) + { + wordLists[i-1].AppendFormat("{0}
    ", sortedWords[(i-1) + (colSize*5)]); + } + + lblWordList1.Text = wordLists[0].ToString(); + lblWordList2.Text = wordLists[1].ToString(); + lblWordList3.Text = wordLists[2].ToString(); + lblWordList4.Text = wordLists[3].ToString(); + lblWordList5.Text = wordLists[4].ToString(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + } +} diff --git a/GUI/LICENSE.txt b/GUI/LICENSE.txt new file mode 100644 index 0000000..6e812ec --- /dev/null +++ b/GUI/LICENSE.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/GUI/Login.aspx b/GUI/Login.aspx new file mode 100644 index 0000000..9e35900 --- /dev/null +++ b/GUI/Login.aspx @@ -0,0 +1,75 @@ +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> +<%@ Page language="c#" CodeFile="login.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Login" %> + + + + HnD::Log in + + + + + + + + +
    +

    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + Please specify your login credentials
    +
     
     
    Nickname   + +
    Password   +
    Log in automatically
      +
    +

    + Forgot your password? +
    +
    +
    + + + + +
    + +
    +
    +
    + + + + diff --git a/GUI/Login.aspx.cs b/GUI/Login.aspx.cs new file mode 100644 index 0000000..1bfadd7 --- /dev/null +++ b/GUI/Login.aspx.cs @@ -0,0 +1,105 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Web.Security; +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind for the login form + /// + public partial class Login : System.Web.UI.Page + { + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnLogin.ServerClick += new System.EventHandler(this.btnLogin_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnLogin_ServerClick(object sender, System.EventArgs e) + { + // try to authenticate the user + UserEntity user = null; + SecurityManager.AuthenticateResult result = SecurityManager.AuthenticateUser(tbxUserName.Value, tbxPassword.Value, out user); + + switch(result) + { + case SecurityManager.AuthenticateResult.AllOk: + // authenticated + // Save session cacheable data + SessionAdapter.LoadUserSessionData(user); + // update last visit date in db + UserManager.UpdateLastVisitDateForUser(user.UserID); + // done + FormsAuthentication.RedirectFromLoginPage(tbxUserName.Value, chkPersistentLogin.Checked); + + // Audit the login action, if it was defined to be logged for this role. + if (SessionAdapter.CheckIfNeedsAuditing(AuditActions.AuditLogin)) + { + SecurityManager.AuditLogin(SessionAdapter.GetUserID()); + } + break; + case SecurityManager.AuthenticateResult.IsBanned: + lblErrorMessage.Text = "You are banned. Login won't work for you."; + break; + case SecurityManager.AuthenticateResult.WrongUsernamePassword: + lblErrorMessage.Text = "You specified a wrong User name - Password combination. Try again."; + break; + } + } + } +} diff --git a/GUI/Logout.aspx b/GUI/Logout.aspx new file mode 100644 index 0000000..66f3dad --- /dev/null +++ b/GUI/Logout.aspx @@ -0,0 +1,30 @@ +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> +<%@ Page language="c#" CodeFile="logout.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Logout" %> + + + + HnD::Log out + + + + + + + +
    +

    + + + + +
    + You're logged out.
    + If you want to log in again, please go to the + log in page. +
    +
    + + + + diff --git a/GUI/Logout.aspx.cs b/GUI/Logout.aspx.cs new file mode 100644 index 0000000..234a4ef --- /dev/null +++ b/GUI/Logout.aspx.cs @@ -0,0 +1,68 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Web.Security; + +namespace SD.HnD.GUI +{ + /// + /// Code behind of the logout form. + /// + public partial class Logout : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // logout user + FormsAuthentication.SignOut(); + + // Abandone session + SessionAdapter.Abandon(); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/GUI/MessageEditor.ascx b/GUI/MessageEditor.ascx new file mode 100644 index 0000000..ffc3da0 --- /dev/null +++ b/GUI/MessageEditor.ascx @@ -0,0 +1,292 @@ +<%@ Control Language="c#" AutoEventWireup="false" CodeFile="MessageEditor.ascx.cs" Inherits="SD.HnD.GUI.MessageEditor" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> + + + + + + + + + + + + + + + + +
    + + +
    + +
    + +
    + +
    +
    + + + + + + + + +
    Preview  + + + + + + + +
    + Posted on: +
    +

    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Subject  + + +    + +
      + +
    +


    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Smileys
    Angry :(Confused :?
    Cool 8)Dissapointed :/
    Embarrassed :!Laugh :D
    Regular :)Sad ;(
    Shocked :oTongue :P
    Wink ;) 
    +
      +   +   +   +   +   +   +   + Color   + Size +
      +
    + +
    +   +     + +
    +
      +
    + +
    +
    diff --git a/GUI/MessageEditor.ascx.cs b/GUI/MessageEditor.ascx.cs new file mode 100644 index 0000000..a383046 --- /dev/null +++ b/GUI/MessageEditor.ascx.cs @@ -0,0 +1,406 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind of the general message editor control. + /// + public abstract partial class MessageEditor : System.Web.UI.UserControl + { + #region Events + public event EventHandler PostMessage; + public event EventHandler CancelAction; + #endregion + + #region Class Member Declarations + private bool _isThreadStart; + private string _threadSubject, _forumName, _originalMessageText, _messageText, _messageTextHTML, + _parserLog, _newThreadSubject, _forumDescription, _messageTextXML, + _messageType = "Message", _buttonText = " Post "; + private bool _parserErrorsOccured, _isSticky, _canBeSticky, _allowEmptyMessage = false, _showAddAttachment, _showSubscribeToThread = true, + _canBeNormal; + #endregion + + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + if(!Page.IsPostBack) + { + _messageText = string.Empty; + _messageTextHTML = string.Empty; + tbxMessage.Text = _originalMessageText; + lblForumName.Text = _forumName; + lblThreadSubject.Text = HttpUtility.HtmlEncode(_threadSubject); + lblTextType.Text = _messageType; + btnPost.Text = _buttonText; + rfvMessage.Enabled = !_allowEmptyMessage; + chkAddAttachment.Visible = _showAddAttachment; + chkSubscribeToThread.Visible = (_showSubscribeToThread && CacheManager.GetSystemData().SendReplyNotifications); + chkSubscribeToThread.Checked = SessionAdapter.GetUserAutoSubscribeToThread(); + + if(_isThreadStart) + { + phSubjectRow.Visible=true; + phHeaderNewThread.Visible=true; + lblForumDescription.Text = _forumDescription; + phCanBeSticky.Visible = _canBeSticky; + rfvSubject.Enabled=true; + if(!_canBeNormal && _canBeSticky) + { + // user can't uncheck sticky and has to be checked. + chkIsSticky.Checked = true; + chkIsSticky.Enabled = false; + } + } + else + { + phHeaderNormal.Visible=true; + } + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + /// + /// General event bubbler. All events of controls contained by this container are streaming through this bubbler. + /// + /// + /// + /// + protected override bool OnBubbleEvent(object source, EventArgs e) + { + bool eventHandled = false; + + CommandEventArgs argsAsCommandEventArgs = e as CommandEventArgs; + + if(argsAsCommandEventArgs!=null) + { + switch(argsAsCommandEventArgs.CommandName) + { + case "btnPreview": + OnPreviewMessage(argsAsCommandEventArgs); + eventHandled = true; + break; + case "btnPost": + OnPostMessage(argsAsCommandEventArgs); + eventHandled = true; + break; + case "btnCancel": + OnCancelMessage(argsAsCommandEventArgs); + eventHandled = true; + break; + } + } + return eventHandled; + } + + /// + /// Event handler for PreviewMessage + /// + /// + protected virtual void OnPreviewMessage(EventArgs e) + { + if(Page.IsValid) + { + lblPreviewBody.Text = TextParser.TransformUBBMessageStringToHTML(tbxMessage.Text, ApplicationAdapter.GetParserData(), out _parserLog, out _parserErrorsOccured, out _messageTextXML); + lblPreviewPostedOn.Text = DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss"); + phPreviewRow.Visible=true; + } + } + + /// + /// Event handler for PostMessage. This message is bubbled up + /// + /// + protected virtual void OnPostMessage(EventArgs e) + { + if(Page.IsValid) + { + if(!_allowEmptyMessage || (tbxMessage.Text.Length>0)) + { + _messageText = tbxMessage.Text; + _messageTextHTML = TextParser.TransformUBBMessageStringToHTML(_messageText, ApplicationAdapter.GetParserData(), out _parserLog, out _parserErrorsOccured, out _messageTextXML); + _isSticky = chkIsSticky.Checked; + _newThreadSubject = tbxSubject.Value.Replace("<", "<"); + } + + // bubble the message through the eventhandler chain + if(PostMessage != null) + { + PostMessage(this, e); + } + } + } + + /// + /// Event handler for CancelMessage + /// + /// + protected virtual void OnCancelMessage(EventArgs e) + { + // do nothin', just bubble + if(CancelAction != null) + { + CancelAction(this, e); + } + } + + + #region Class Property Declarations + /// + /// Sets the forum description. + /// + /// The forum description. + public string ForumDescription + { + set { _forumDescription = value; } + } + + /// + /// Sets a value indicating whether this instance can be sticky. + /// + /// + /// true if this instance can be sticky; otherwise, false. + /// + public bool CanBeSticky + { + set { _canBeSticky = value; } + } + + + /// + /// Sets a value indicating whether the new thread can be a normal thread (non-sticky). + /// + public bool CanBeNormal + { + set { _canBeNormal = value; } + } + + /// + /// Gets a value indicating whether this instance is sticky. + /// + /// true if this instance is sticky; otherwise, false. + public bool IsSticky + { + get { return _isSticky;} + } + + /// + /// Gets the new thread subject. + /// + /// The new thread subject. + public string NewThreadSubject + { + get { return _newThreadSubject; } + } + + /// + /// Gets / Sets a value indicating whether this instance is thread start. + /// + public bool IsThreadStart + { + get { return _isThreadStart; } + set { _isThreadStart = value; } + } + + /// + /// Gets a value indicating whether [parser errors occured]. + /// + /// true if [parser errors occured]; otherwise, false. + public bool ParserErrorsOccured + { + get { return _parserErrorsOccured; } + } + + /// + /// Gets the parser log. + /// + /// The parser log. + public string ParserLog + { + get { return _parserLog; } + } + + /// + /// Sets the thread subject. + /// + /// The thread subject. + public string ThreadSubject + { + set { _threadSubject = value; } + } + + /// + /// Sets the name of the forum. + /// + /// The name of the forum. + public string ForumName + { + set { _forumName = value; } + } + + /// + /// Sets the original message text. + /// + /// The original message text. + public string OriginalMessageText + { + set { _originalMessageText = value; } + } + + /// + /// Gets the message text. + /// + /// The message text. + public string MessageText + { + get { return _messageText; } + } + + /// + /// Gets the message text HTML. + /// + /// The message text HTML. + public string MessageTextHTML + { + get { return _messageTextHTML; } + } + + /// + /// Gets the message text XML. + /// + /// The message text XML. + public string MessageTextXML + { + get { return _messageTextXML;} + } + + /// + /// Gets / sets messageType + /// + public string MessageType + { + get + { + return _messageType; + } + set + { + _messageType = value; + } + } + + /// + /// Gets / sets ButtonText + /// + public string ButtonText + { + get + { + return _buttonText; + } + set + { + _buttonText = value; + } + } + + /// + /// Gets / sets AllowEmptyMessage + /// + public bool AllowEmptyMessage + { + get + { + return _allowEmptyMessage; + } + set + { + _allowEmptyMessage = value; + } + } + + /// + /// Gets a value indicating whether AddAttachment is checked or not. + /// + public bool AddAttachment + { + get { return chkAddAttachment.Checked; } + } + + /// + /// Gets a value indicating whether SubscribeToThread is checked or not. + /// + public bool SubscribeToThread + { + get { return chkSubscribeToThread.Checked && chkSubscribeToThread.Visible; } + } + + /// + /// Sets a value indicating whether AddAttachment checkbox should be shown + /// + public bool ShowAddAttachment + { + set { _showAddAttachment = value; } + } + + + /// + /// Sets a value indicating whether SubscribeToMessage checkbox should be shown + /// + public bool ShowSubscribeToThread + { + set { _showSubscribeToThread = value; } + } + #endregion + } +} diff --git a/GUI/Messages.aspx b/GUI/Messages.aspx new file mode 100644 index 0000000..85aa5b9 --- /dev/null +++ b/GUI/Messages.aspx @@ -0,0 +1,319 @@ +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Page language="c#" CodeFile="Messages.aspx.cs" AutoEventWireup="true" Inherits="SD.HnD.GUI.Messages"%> +<%@ Register TagPrefix="HnD" TagName="PageList" Src="PageList.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Import namespace="System.Web" %> +<%@ Import namespace="System.Data" %> +<%@ Import Namespace="SD.HnD.GUI" %> + + + HnD::List all messages of thread: <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> + + + + + + + + + + +
    + +
    + + +
    + + + + + + + + + + + + + + + + + + +
    +
    + You are here: Home > + > > <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> +
     
    + + + + + + + + + + + + + + + +
    Support Queue Management
    Claimed by + + +    + + + In Queue + + + +   +
    Claimed on  +
    +
     
    + + + + + + + +
    Memo  (Edit)
    + +
    +
    + + + + + + + + + + + + + + + + +
     

    +
    +
    + +
    +
    + New Thread +  |  + New Message +
    +
    +
    + + + + + +
    + +
    + <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> + +
    + Page:/  +
    +
    + + +   + + + + + + + + + + +   +
    +
    + + + + + + + + + + + + + + + + + + +
    + + + + + +
    PosterMessage
    +
    + + + + + +
    + + <%# Eval("NickName")%>
    + <%# Eval("UserTitleDescription")%> +

    +
    + +
    +
    +
    + + Location:
    <%# Eval("Location")%>
    + Joined on:
    <%# ((DateTime)Eval("JoinDate")).ToString("dd-MMM-yyyy HH:mm:ss")%>
    + Posted:
    <%# Eval("AmountOfPostings")%> posts
    +
    +
    + + + + + + + + + + + + +
    + # + Posted on: <%# ((DateTime)Eval("PostingDate")).ToString(@"dd-MMM-yyyy HH:mm:ss")%>. Posted from IP: + + + + +   + + Delete + | + Edit + | + Quote + +
    + <%# Eval("MessageTextAsHTML")%> +
    + <%# Eval("SignatureAsHTML")%>  + + Top +
    +
    +
    + + + + + + +
    + + <%# Eval("NickName")%>
    + <%# Eval("UserTitleDescription")%> +

    +
    + +
    +
    +
    + + Location:
    <%# Eval("Location")%>
    + Joined on:
    <%# ((DateTime)Eval("JoinDate")).ToString("dd-MMM-yyyy HH:mm:ss")%>
    + Posted:
    <%# Eval("AmountOfPostings")%> posts
    +
    +
    + + + + + + + + + + + + +
    + # + Posted on: <%# ((DateTime)Eval("PostingDate")).ToString(@"dd-MMM-yyyy HH:mm:ss")%>. Posted from IP: + + + + +   + + Delete + | + Edit + | + Quote + +
    + <%# Eval("MessageTextAsHTML")%> +

    +
    + <%# Eval("SignatureAsHTML")%>  + + Top +
    +
    +
    + +
    +
    + + + + + + +
      + New Thread +  |  + New Message +
    +
    +
    + + + + diff --git a/GUI/Messages.aspx.cs b/GUI/Messages.aspx.cs new file mode 100644 index 0000000..14e422e --- /dev/null +++ b/GUI/Messages.aspx.cs @@ -0,0 +1,538 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; +using System.Globalization; +using SD.HnD.DAL.TypedListClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind class for Messages.aspx, which renders a page of messages in a given thread. + /// + public partial class Messages : System.Web.UI.Page + { + #region Class Member declarations + private int _startMessageNo; + private ThreadEntity _thread; + private bool _showEditMessageLink, _showDeleteMessageLink, _showQuoteMessageLink, _showIPAddresses, _forumAllowsAttachments, + _userMayAddAttachments, _userCanCreateThreads, _userMayDoForumSpecificThreadManagement, _userMayDoSystemWideThreadManagement, + _userMayEditMemo, _userMayMarkThreadAsDone, _userMayManageSupportQueueContents, _threadStartedByCurrentUser, _userMayAddNewMessages, + _userMayDoBasicThreadOperations; + #endregion + + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread == null) + { + // not found, return to start page + Response.Redirect("default.aspx"); + } + + // Check credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx"); + } + + _startMessageNo = HnDGeneralUtils.TryConvertToInt(Request.QueryString["StartAtMessage"]); + bool highLightSearchResults = (HnDGeneralUtils.TryConvertToInt(Request.QueryString["HighLight"]) == 1); + + if(!_thread.IsClosed) + { + if(_thread.IsSticky) + { + _userMayAddNewMessages = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAndEditMessageInSticky); + } + else + { + _userMayAddNewMessages = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAndEditMessage); + } + // set show*link class members. These have to be set despite the postback status, as they're used in the repeater. Only set + // them to true if the thread isn't closed. They've been initialized to false already. + _showEditMessageLink = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.EditDeleteOtherUsersMessages); + _showDeleteMessageLink = _showEditMessageLink; + _showQuoteMessageLink = _userMayAddNewMessages; + } + + // show user IP addresses if the user has system admin rights, security admin rights or user admin rights. + _showIPAddresses = (SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement) || + SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement) || + SessionAdapter.HasSystemActionRight(ActionRights.UserManagement)); + // Get the forum entity related to the thread. Use BL class. We could have used Lazy loading, though for the sake of separation, we'll + // call into the BL class. + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // not found, orphaned thread, return to default page. + Response.Redirect("default.aspx"); + } + _forumAllowsAttachments = (forum.MaxNoOfAttachmentsPerMessage > 0); + + // check if the user can view this thread. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !_thread.IsSticky) + { + // can't view this thread, it isn't visible to the user + Response.Redirect("default.aspx", true); + } + + _threadStartedByCurrentUser = (_thread.StartedByUserID == SessionAdapter.GetUserID()); + _userMayAddAttachments = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAttachment); + _userCanCreateThreads = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddNormalThread) || + SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddStickyThread); + _userMayDoForumSpecificThreadManagement = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ForumSpecificThreadManagement); + _userMayDoSystemWideThreadManagement = SessionAdapter.HasSystemActionRight(ActionRights.SystemWideThreadManagement); + _userMayEditMemo = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.EditThreadMemo); + _userMayMarkThreadAsDone = (SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.FlagThreadAsDone) || _threadStartedByCurrentUser); + _userMayManageSupportQueueContents = SessionAdapter.HasSystemActionRight(ActionRights.QueueContentManagement); + _userMayDoBasicThreadOperations = (SessionAdapter.GetUserID() > 0); + + if(!Page.IsPostBack) + { + plPageListBottom.HighLight = highLightSearchResults; + plPageListTop.HighLight = highLightSearchResults; + litHighLightLogic.Visible = highLightSearchResults; + + if(highLightSearchResults) + { + // make highlighting of search results possible + string searchTerms = SessionAdapter.GetSearchTerms(); + if(searchTerms == null) + { + searchTerms = string.Empty; + } + this.ClientScript.RegisterHiddenField("searchTerms", searchTerms.Replace("AND", "").Replace("OR", "").Replace("and", "").Replace("or", "").Replace("\"", "")); + } + else + { + // replace hightlighting scriptblock. + this.ClientScript.RegisterClientScriptBlock(this.GetType(), "onLoad", ""); + } + + if(_userMayManageSupportQueueContents) + { + // fill support queue management area with data. + SupportQueueCollection supportQueues = CacheManager.GetAllSupportQueues(); + cbxSupportQueues.DataSource = supportQueues; + cbxSupportQueues.DataBind(); + + SupportQueueEntity containingQueue = SupportQueueGuiHelper.GetQueueOfThread(_thread.ThreadID); + if(containingQueue != null) + { + cbxSupportQueues.SelectedValue = containingQueue.QueueID.ToString(); + // get claim info + SupportQueueThreadEntity supportQueueThreadInfo = SupportQueueGuiHelper.GetSupportQueueThreadInfo(_thread.ThreadID, true); + if((supportQueueThreadInfo != null) && supportQueueThreadInfo.ClaimedByUserID.HasValue) + { + // claimed by someone + lblClaimDate.Text = supportQueueThreadInfo.ClaimedOn.Value.ToString("dd-MMM-yyyy HH:mm.ss", DateTimeFormatInfo.InvariantInfo); + lnkClaimerThread.Visible = true; + lblNotClaimed.Visible = false; + lnkClaimerThread.Text = supportQueueThreadInfo.ClaimedByUser.NickName; + lnkClaimerThread.NavigateUrl += supportQueueThreadInfo.ClaimedByUserID.ToString(); + btnClaim.Visible = false; + btnRelease.Visible = true; + } + else + { + // not claimed + lblClaimDate.Text = string.Empty; + btnClaim.Visible = true; + btnRelease.Visible = false; + } + } + } + phSupportQueueManagement.Visible = _userMayManageSupportQueueContents; + + if((_thread.Memo.Length > 0) && _userMayEditMemo) + { + // convert memo contents to HTML so it's displayed above the thread. + string parserLog, messageTextXml; + bool errorsOccured = false; + string memoAsHTML = TextParser.TransformUBBMessageStringToHTML(_thread.Memo, ApplicationAdapter.GetParserData(), out parserLog, out errorsOccured, out messageTextXml); + lblMemo.Text = memoAsHTML; + } + phMemo.Visible = _userMayEditMemo; + + bool isBookmarked = UserGuiHelper.CheckIfThreadIsAlreadyBookmarked(SessionAdapter.GetUserID(), threadID); + bool isSubscribed = UserGuiHelper.CheckIfThreadIsAlreadySubscribed(SessionAdapter.GetUserID(), threadID); + btnBookmarkThread.Visible = !isBookmarked && _userMayDoBasicThreadOperations; + btnUnbookmarkThread.Visible = isBookmarked && _userMayDoBasicThreadOperations; + bool sendReplyNotifications = CacheManager.GetSystemData().SendReplyNotifications; + btnSubscribeToThread.Visible = !isSubscribed && _userMayDoBasicThreadOperations && sendReplyNotifications; + btnUnsubscribeFromThread.Visible = isSubscribed && _userMayDoBasicThreadOperations && sendReplyNotifications; + + // fill the page's content + lnkThreads.Text = HttpUtility.HtmlEncode(forum.ForumName); + lnkThreads.NavigateUrl += "?ForumID=" + _thread.ForumID; + lblForumName_Header.Text = forum.ForumName; + lblSectionName.Text = CacheManager.GetSectionName(forum.SectionID); + + // Check if the current user is allowed to add new messages to the thread. + + // these controls are not visible by default, show them if necessary + if(_userMayDoForumSpecificThreadManagement || _userMayDoSystemWideThreadManagement) + { + if(!_thread.IsClosed && _userMayAddNewMessages) + { + lnkCloseThread.Visible=true; + lnkCloseThread.NavigateUrl+="?ThreadID=" + threadID + "&StartAtMessage=" + _startMessageNo; + } + lnkEditThreadProperties.Visible=true; + lnkEditThreadProperties.NavigateUrl+="?ThreadID=" + threadID; + } + + if(_userMayDoSystemWideThreadManagement) + { + lnkMoveThread.Visible=true; + lnkMoveThread.NavigateUrl+="?ThreadID=" + threadID; + lnkDeleteThread.Visible=true; + lnkDeleteThread.NavigateUrl+="?ThreadID=" + threadID; + } + + btnThreadDone.Visible = _thread.MarkedAsDone; + btnThreadNotDone.Visible = !_thread.MarkedAsDone; + btnThreadDone.Enabled = _userMayMarkThreadAsDone; + btnThreadNotDone.Enabled = _userMayMarkThreadAsDone; + + if(_userMayEditMemo) + { + lnkEditMemo.Visible=true; + lnkEditMemo.NavigateUrl+="?ThreadID=" + threadID + "&StartAtMessage=" + _startMessageNo; + } + + // These controls are visible by default. Hide them when the user can't create threads on this forum + if(_userCanCreateThreads) + { + lnkNewThreadBottom.NavigateUrl += "?ForumID=" + _thread.ForumID + "&StartAtMessage=" + _startMessageNo; + lnkNewThreadTop.NavigateUrl += "?ForumID=" + _thread.ForumID + "&StartAtMessage=" + _startMessageNo; + } + else + { + lnkNewThreadBottom.Visible = false; + lnkNewThreadTop.Visible = false; + } + + if(_userMayAddNewMessages) + { + lnkNewMessageBottom.NavigateUrl += "?ThreadID=" + threadID + "&StartAtMessage=" + _startMessageNo; + lnkNewMessageTop.NavigateUrl += "?ThreadID=" + threadID + "&StartAtMessage=" + _startMessageNo; + } + else + { + lnkNewMessageBottom.Visible = false; + lnkNewMessageTop.Visible = false; + } + lblSeparatorTop.Visible = (_userMayAddNewMessages && _userCanCreateThreads); + lblSeparatorBottom.Visible = (_userMayAddNewMessages && _userCanCreateThreads); + + // The amount of postings in this thread are in the dataview row, which should contain just 1 row. + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + int amountOfMessages = ThreadGuiHelper.GetTotalNumberOfMessagesInThread(threadID); + int amountOfPages = ((amountOfMessages-1) / maxAmountMessagesPerPage)+1; + int currentPageNo = (_startMessageNo / maxAmountMessagesPerPage)+1; + lblCurrentPage.Text = currentPageNo.ToString(); + lblTotalPages.Text = amountOfPages.ToString(); + + lnkPrintThread.NavigateUrl += "?ThreadID=" + threadID; + + plPageListBottom.AmountMessages = amountOfMessages; + plPageListBottom.StartMessageNo = _startMessageNo; + plPageListBottom.ThreadID = threadID; + plPageListTop.AmountMessages = amountOfMessages; + plPageListTop.StartMessageNo = _startMessageNo; + plPageListTop.ThreadID = threadID; + + // Get messages and bind it to the repeater control. Use the startmessage to get only the message visible on the current page. + MessagesInThreadTypedList messages = ThreadGuiHelper.GetAllMessagesInThreadAsTypedList(threadID, currentPageNo, maxAmountMessagesPerPage); + rptMessages.DataSource = messages; + rptMessages.DataBind(); + } + } + + /// + /// Event handler for the ItemDataBound for the repeater control. Will set/reset controls inside the repeater + /// template according to the user and his rights. + /// + /// + /// + protected void rptMessages_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + // check if the thread is closed. If so, no editing nor new postings are allowed. + if(!_thread.IsClosed) + { + HyperLink lnkEditMessage = (HyperLink)e.Item.FindControl("lnkEditMessage"); + HyperLink lnkDeleteMessage = (HyperLink)e.Item.FindControl("lnkDeleteMessage"); + HyperLink lnkNewMessageWQuote = (HyperLink)e.Item.FindControl("lnkNewMessageWQuote"); + + // editing and new messages are allowed when the rights are ok and the user isn't the AC + // Check if the current message is posted by the current user + bool showEditLink = _showEditMessageLink; + int currentUserID = SessionAdapter.GetUserID(); + if ((currentUserID == (int)((DataRowView)e.Item.DataItem)["UserID"]) && (currentUserID != 0)) + { + // yes. so enable editing + showEditLink=true; + } + + // you can only delete a message that's not the first message of the first thread. + int currentPageNumber = HnDGeneralUtils.TryConvertToInt(lblCurrentPage.Text); + bool showDeleteLink = (currentPageNumber > 1 || e.Item.ItemIndex > 0) && _showDeleteMessageLink; + + lnkEditMessage.Visible = showEditLink; + lnkNewMessageWQuote.Visible=_showQuoteMessageLink; + lnkDeleteMessage.Visible = showDeleteLink; + + if(showEditLink && showDeleteLink) + { + // enable separator lable + ((Label)e.Item.FindControl("lblMessageCmdSepDeleteEdit")).Visible=true; + } + + if((showEditLink && _showQuoteMessageLink)||(showDeleteLink && _showQuoteMessageLink)) + { + // enable separator lable + ((Label)e.Item.FindControl("lblMessageCmdSepEditQuote")).Visible=true; + } + } + break; + } + } + + + protected void btnSet_Click(object sender, EventArgs e) + { + if(!_userMayManageSupportQueueContents) + { + return; + } + + // move this thread to a support queue. + // check the selected ID to see if it is the same as the current Queue. If so, ignore, otherwise set the queue. + int selectedQueueID = HnDGeneralUtils.TryConvertToInt(cbxSupportQueues.SelectedValue); + + SupportQueueEntity containingQueue = SupportQueueGuiHelper.GetQueueOfThread(_thread.ThreadID); + // now set the queue if: + // a) the thread isn't in a queue and the selected queueID > 0 (so not None) + // b) the thread is in a queue and the selected queueuID isn't the id of the queue containing the thread + if(((containingQueue == null) && (selectedQueueID != -1)) || ((containingQueue != null) && (containingQueue.QueueID != selectedQueueID))) + { + // Set the queue. if the new queue is -1, remove from queue. + if(selectedQueueID > 0) + { + SupportQueueManager.AddThreadToQueue(_thread.ThreadID, selectedQueueID, SessionAdapter.GetUserID(), null); + } + else + { + SupportQueueManager.RemoveThreadFromQueue(_thread.ThreadID, null); + } + } + + // done redirect to this page to refresh. + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + + protected void btnClaim_Click(object sender, EventArgs e) + { + if(!_userMayManageSupportQueueContents) + { + return; + } + + // claim this thread + SupportQueueManager.ClaimThread(SessionAdapter.GetUserID(), _thread.ThreadID); + // done redirect to this page to refresh. + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + + protected void btnRelease_Click(object sender, EventArgs e) + { + if(!_userMayManageSupportQueueContents) + { + return; + } + + // release any claim on this thread. + SupportQueueManager.ReleaseClaimOnThread( _thread.ThreadID); + // done redirect to this page to refresh. + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + protected void btnBookmarkThread_Click(object sender, System.Web.UI.ImageClickEventArgs e) + { + if(!_userMayDoBasicThreadOperations) + { + return; + } + // bookmark this thread. + bool result = UserManager.AddThreadToBookmarks(SessionAdapter.GetUserID(), _thread.ThreadID); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + protected void btnUnbookmarkThread_Click(object sender, System.Web.UI.ImageClickEventArgs e) + { + if(!_userMayDoBasicThreadOperations) + { + return; + } + // remove the bookmark on this thread. + UserManager.RemoveSingleBookmark(_thread.ThreadID, SessionAdapter.GetUserID()); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + protected void btnThreadNotDone_Click(object sender, System.Web.UI.ImageClickEventArgs e) + { + if(!_userMayMarkThreadAsDone) + { + return; + } + // thread is done, mark it as such. + ThreadManager.MarkThreadAsDone(_thread.ThreadID); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + protected void btnThreadDone_Click(object sender, ImageClickEventArgs e) + { + if(!_userMayMarkThreadAsDone) + { + return; + } + // thread is re-opened, mark it as not done. + ThreadManager.UnMarkThreadAsDone(_thread.ThreadID, SessionAdapter.GetUserID()); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + protected void btnSubscribeToThread_Click(object sender, ImageClickEventArgs e) + { + if(!_userMayDoBasicThreadOperations) + { + return; + } + bool result = UserManager.AddThreadToSubscriptions(_thread.ThreadID, SessionAdapter.GetUserID(), null); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + protected void btnUnSubscribeFromThread_Click(object sender, ImageClickEventArgs e) + { + if(!_userMayDoBasicThreadOperations) + { + return; + } + UserManager.RemoveSingleSubscription(_thread.ThreadID, SessionAdapter.GetUserID()); + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startMessageNo); + } + + + #region Class Property Declarations + /// + /// Gets the thread subject. + /// + /// The thread subject. + protected string ThreadSubject + { + get + { + if(_thread != null) + { + return _thread.Subject; + } + else + { + return string.Empty; + } + } + } + + /// + /// Gets the thread ID. + /// + /// The thread ID. + protected int ThreadID + { + get + { + if(_thread != null) + { + return _thread.ThreadID; + } + else + { + return 0; + } + } + } + + /// + /// Gets a value indicating whether IP addresses should be shown. Used by the HTML code + /// + protected bool ShowIPAddresses + { + get { return _showIPAddresses; } + } + + + /// + /// Gets a value indicating whether [forum allows attachments]. + /// + protected bool ForumAllowsAttachments + { + get { return _forumAllowsAttachments; } + } + + /// + /// Gets a value indicating whether [user may add attachments]. + /// + protected bool UserMayAddAttachments + { + get { return _userMayAddAttachments; } + } + #endregion +} +} diff --git a/GUI/MoveThread.aspx b/GUI/MoveThread.aspx new file mode 100644 index 0000000..4195649 --- /dev/null +++ b/GUI/MoveThread.aspx @@ -0,0 +1,87 @@ +<%@ Page language="c#" CodeFile="MoveThread.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.MoveThread" %> + +<%@ Register Assembly="SD.LLBLGen.Pro.ORMSupportClasses.NET20" Namespace="SD.LLBLGen.Pro.ORMSupportClasses" TagPrefix="llblgenpro" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> + + + + HnD::Administrate::Move a thread. + + + + + + + +
    + + +
    +
    + + + + +
    +

    Move a thread

    + Below you can select the forum whereto you are moving the thread mentioned below. First select the section, then the forum and after that click + Move if you want to move the thread to the forum selected. +
    +
    + + + + + + + + + + +
    + Select the forum to move the thread to. +
    + + + + + + + + + + + + + + + + + + + + + +

    Thread 
    Section  + +
    Forum  + +
      +
    +     + +
    +
     
    + + + + + +
    + + + + diff --git a/GUI/MoveThread.aspx.cs b/GUI/MoveThread.aspx.cs new file mode 100644 index 0000000..785200f --- /dev/null +++ b/GUI/MoveThread.aspx.cs @@ -0,0 +1,169 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL; +using SD.HnD.Utility; +using SD.LLBLGen.Pro.ORMSupportClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file for the MoveThread form. + /// + public partial class MoveThread : System.Web.UI.Page + { + #region Class Member Declarations + private ThreadEntity _thread; + #endregion + + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread == null) + { + // not found, return to default page + Response.Redirect("default.aspx", true); + } + + // Check credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx"); + } + + bool userMayMoveThread = SessionAdapter.HasSystemActionRight(ActionRights.SystemWideThreadManagement); + if(!userMayMoveThread) + { + // doesn't have access to this forum. redirect + Response.Redirect("Messages.aspx?ThreadID=" + threadID, true); + } + + // check if the user can view this thread. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !_thread.IsSticky) + { + // can't view this thread, it isn't visible to the user + Response.Redirect("default.aspx", true); + } + + if(!Page.IsPostBack) + { + // fill the page's content. Bind the known sections + SectionCollection sections = CacheManager.GetAllSections(); + cbxSections.DataSource = sections; + cbxSections.DataBind(); + + lblThreadSubject.Text = HttpUtility.HtmlEncode(_thread.Subject); + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // Orphaned thread + Response.Redirect("default.aspx", true); + } + + // pre-select the section the forum is currently in. Do that with an in-memory search through the known sections. + SectionEntity toFind = new SectionEntity(); + toFind.Fields[(int)SectionFieldIndex.SectionID].ForcedCurrentValueWrite(forum.SectionID); + toFind.IsNew=false; + int index = sections.IndexOf(toFind); + if(index >= 0) + { + cbxSections.SelectedIndex = index; + } + } + } + + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnMove.ServerClick += new System.EventHandler(this.btnMove_ServerClick); + this.btnCancel.ServerClick += new System.EventHandler(this.btnCancel_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnMove_ServerClick(object sender, System.EventArgs e) + { + // Move the thread + int newForumID = Convert.ToInt32(cbxForums.SelectedItem.Value); + bool result = ThreadManager.MoveThread(_thread.ThreadID, newForumID); + + // done for now + Response.Redirect("Threads.aspx?ForumID=" + newForumID, true); + } + + private void btnCancel_ServerClick(object sender, System.EventArgs e) + { + // do nothing + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID, true); + } + + + /// + /// Handles the PerformSelect event of the _forumsDS control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void _forumsDS_PerformSelect(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs e) + { + int selectedSectionID = HnDGeneralUtils.TryConvertToInt(cbxSections.SelectedValue); + _forumsDS.EntityCollection = ForumGuiHelper.GetAllForumsInSection(selectedSectionID); + } + } +} diff --git a/GUI/MyThreads.aspx b/GUI/MyThreads.aspx new file mode 100644 index 0000000..f2b6ad9 --- /dev/null +++ b/GUI/MyThreads.aspx @@ -0,0 +1,126 @@ +<%@ Page language="c#" CodeFile="MyThreads.aspx.cs" AutoEventWireup="true" Inherits="SD.HnD.GUI.MyThreads" ValidateRequest="false" %> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register Src="Footer.ascx" TagName="PageFooter" TagPrefix="HnD" %> +<%@ Register TagPrefix="HnD" TagName="PageList" Src="PageList.ascx"%> +<%@ Register TagPrefix="HnD" TagName="MyThreadsPageList" Src="MyThreadsPageList.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageLegend" Src="PageLegend.ascx"%> +<%@ Import namespace="System.Web" %> +<%@ Import Namespace="System.Globalization" %> +<%@ Import Namespace="SD.HnD.GUI" %> + + + + HnD::My threads + + + + + +
    +
    + + + + + + + + + + + + + + + + + + +
    + Number of threads found: (Maximum browsable: 500)
    +
    +
    + +
    +
    +
    + The threads I participated in +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     Thread subjectRepliesViewsLast post
    + + + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +    
    +
    + Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    +
    <%# Convert.ToInt32(Eval("AmountMessages")) - 1%><%# Eval("NumberOfViews")%> +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On:
    +
    + + + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +    
    +
    + Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    +
    <%# Convert.ToInt32(Eval("AmountMessages")) - 1%><%# Eval("NumberOfViews")%> +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On:
    +
    + +
    + +
    + +
    +
    + + + diff --git a/GUI/MyThreads.aspx.cs b/GUI/MyThreads.aspx.cs new file mode 100644 index 0000000..5e0de08 --- /dev/null +++ b/GUI/MyThreads.aspx.cs @@ -0,0 +1,183 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// Code behind of the MyThreads viewer form. + /// + public partial class MyThreads : System.Web.UI.Page + { + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int callingUserID = SessionAdapter.GetUserID(); + if(callingUserID == 0) + { + // anonymous, redirect + Response.Redirect("default.aspx", true); + } + + if(!Page.IsPostBack) + { + int rowCount = 0; + int currentPage = HnDGeneralUtils.TryConvertToInt(Request["Page"]); + if(currentPage == 0) + { + currentPage = 1; + // reset # of rows in the session. + rowCount = 0; + } + else + { + rowCount = SessionAdapter.GetTempResult("MyThreadsRowCount"); + } + + // check if the rowCount is valid + if(rowCount <= 0) + { + // reload rowCount + rowCount = UserGuiHelper.GetRowCountLastThreadsForUserAsDataView(SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum), + callingUserID, SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), + callingUserID); + SessionAdapter.SetTempResult("MyThreadsRowCount", rowCount); + } + + short pageSize = CacheManager.GetSystemData().PageSizeSearchResults; + if(pageSize <= 0) + { + pageSize = 50; + } + + int rowCountCapped = rowCount; + if(rowCount > 500) + { + // maximum is 500 + rowCountCapped = 500; + lblCappingWarning.Visible = true; + } + int amountPages = (rowCountCapped / pageSize); + if((amountPages * pageSize) < rowCountCapped) + { + amountPages++; + } + + plPageListBottom.AmountPages = amountPages; + plPageListBottom.CurrentPage = currentPage; + plPageListTop.AmountPages = amountPages; + plPageListTop.CurrentPage = currentPage; + lblAmountThreads.Text = rowCount.ToString(); + + DataView lastThreads = UserGuiHelper.GetLastThreadsForUserAsDataView(SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum), + callingUserID, SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), + callingUserID, pageSize, currentPage); + rpThreads.DataSource = lastThreads; + rpThreads.DataBind(); + } + } + + + /// + /// Event handler which will be called every time a row in the Repeater rpThreads is bound to a row in the view. + /// + /// + /// + protected void rpThreads_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + // Thread has always a last posting date: a thread has at least 1 posting. + DateTime threadLastPostingDate = (DateTime)(((DataRowView)e.Item.DataItem)["ThreadLastPostingDate"]); + DateTime lastVisitDate = SessionAdapter.GetLastVisitDate(); + bool isSticky = (bool)(((DataRowView)e.Item.DataItem)["IsSticky"]); + bool isClosed = (bool)(((DataRowView)e.Item.DataItem)["IsClosed"]); + + // date is not 0, check if the date is > than the date in the session variable. If so, the posting is newer and we + // should visualize the New Messages image, otherwise the No new Messages image. Also take into account + // the type of the thread: sticky, closed or normal. + System.Web.UI.WebControls.Image imgIconPosts; + + if(threadLastPostingDate > lastVisitDate) + { + // there are new messages since last visit + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPosts"); + } + } + } + else + { + // no new messages + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPosts"); + } + } + } + imgIconPosts.Visible = true; + break; + } + } + } +} diff --git a/GUI/MyThreadsPageList.ascx b/GUI/MyThreadsPageList.ascx new file mode 100644 index 0000000..79ee470 --- /dev/null +++ b/GUI/MyThreadsPageList.ascx @@ -0,0 +1,9 @@ +<%@ Control Language="c#" AutoEventWireup="false" CodeFile="MyThreadsPageList.ascx.cs" Inherits="SD.HnD.GUI.MyThreadsPageList" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> + + Pages: + + + <%# (int)(Container.DataItem)%> + <%# (int)(Container.DataItem)%> + + diff --git a/GUI/MyThreadsPageList.ascx.cs b/GUI/MyThreadsPageList.ascx.cs new file mode 100644 index 0000000..ab953c3 --- /dev/null +++ b/GUI/MyThreadsPageList.ascx.cs @@ -0,0 +1,124 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI +{ + /// + /// Page list control for the MyThreads page + /// + public partial class MyThreadsPageList : System.Web.UI.UserControl + { + + #region Class Member Declarations + private int _amountPages, _currentPage; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + int[] pageNos = new int[_amountPages]; + + for(int i=0;i<_amountPages;i++) + { + pageNos[i]=(i+1); + } + + rptPageList.DataSource = pageNos; + rptPageList.DataBind(); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + this.rptPageList.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.rptPageList_ItemDataBound); + } + #endregion + + /// + /// Event handler for the ItemDataBound event for the repeater control. In here the decision is made + /// if the current item will be a link (we're not on this page) or not (thus a label) + /// + /// + /// + private void rptPageList_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + if(_currentPage == (int)e.Item.DataItem) + { + Label lblMessagePage = (Label)e.Item.FindControl("lblMessagesPage"); + lblMessagePage.Visible=true; + } + else + { + HyperLink lnkResultPage = (HyperLink)e.Item.FindControl("lnkResultPage"); + lnkResultPage.NavigateUrl += (int)e.Item.DataItem; + lnkResultPage.Visible=true; + } + break; + } + } + + #region Class Property Declarations + /// + /// sets amountPages + /// + public int AmountPages + { + set + { + _amountPages = value; + } + } + + /// + /// sets currentPage + /// + public int CurrentPage + { + set + { + _currentPage = value; + } + } + #endregion + } +} diff --git a/GUI/NewMessage.aspx b/GUI/NewMessage.aspx new file mode 100644 index 0000000..067e90f --- /dev/null +++ b/GUI/NewMessage.aspx @@ -0,0 +1,120 @@ +<%@ Page language="c#" CodeFile="NewMessage.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.NewMessage" ValidateRequest="false" + Async="true"%> +<%@ Import namespace="SD.HnD.DAL.EntityClasses" %> +<%@ Import namespace="System.Data" %> +<%@ Import namespace="System.Web" %> +<%@ Register TagPrefix="HnD" TagName="MessageEditor" Src="MessageEditor.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> + + + + HnD::Add a new message to thread: <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> + + + +
    + + + + + + + + + + + + +
    +
    + You are here: Home > > + > + > Add new message +

    +
     
    + + + + + + + +
    Memo
    + +
    +
     
    + + + + +

    + + + + + + + +
    + Last posting in thread +
    + + + + + + + +
    + + + + + +
    PosterMessage
    +
    + + + + + +
    +
    + +

    + + Location:

    + Joined on:

    + Posted:
    posts
    +
    +
    + + + + + + + + + + + + +
    Posted on:  
    + +
    + + + Top +
    +
    +
    +
    +
    + +
    + + + + diff --git a/GUI/NewMessage.aspx.cs b/GUI/NewMessage.aspx.cs new file mode 100644 index 0000000..cd1a640 --- /dev/null +++ b/GUI/NewMessage.aspx.cs @@ -0,0 +1,278 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.Utility; + +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind of the New message form. + /// + public partial class NewMessage : System.Web.UI.Page + { + #region Class Member Declarations + private int _startAtMessageIndex, _quoteMessageID; + private ThreadEntity _thread; + #endregion + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread == null) + { + // not found, return to default page + Response.Redirect("default.aspx", true); + } + + _startAtMessageIndex = HnDGeneralUtils.TryConvertToInt(Request.QueryString["StartAtMessage"]); + _quoteMessageID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["QuoteMessageID"]); + + // Check credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx"); + } + + // Check if the current user is allowed to add new messages to the thread. + bool userMayAddNewMessages=false; + if(!_thread.IsClosed) + { + if(_thread.IsSticky) + { + if(SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAndEditMessageInSticky)) + { + userMayAddNewMessages=true; + } + } + else + { + if(SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAndEditMessage)) + { + userMayAddNewMessages=true; + } + } + } + + if(!userMayAddNewMessages) + { + // is not allowed to post a new message + Response.Redirect("Messages.aspx?ThreadID=" + threadID, true); + } + + // use BL class. We could have used Lazy loading, though for the sake of separation, we'll call into the BL class. + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // orphaned thread + Response.Redirect("default.aspx"); + } + + // check if the user can view the thread the message is in. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers)) + { + // can't add a message, it's in a thread which isn't visible to the user + Response.Redirect("default.aspx", true); + } + + meMessageEditor.ShowAddAttachment = ((forum.MaxNoOfAttachmentsPerMessage > 0) && + SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AddAttachment)); + meMessageEditor.ShowSubscribeToThread = !UserGuiHelper.CheckIfThreadIsAlreadySubscribed(SessionAdapter.GetUserID(), _thread.ThreadID); + + // User is able to post a new message to the current thread. + if(!Page.IsPostBack) + { + // fill the page's content + lnkThreads.Text = HttpUtility.HtmlEncode(forum.ForumName); + lnkThreads.NavigateUrl += "?ForumID=" + _thread.ForumID; + meMessageEditor.ForumName = forum.ForumName; + meMessageEditor.ThreadSubject = _thread.Subject; + lblSectionName.Text = CacheManager.GetSectionName(forum.SectionID); + lnkMessages.NavigateUrl+=threadID; + lnkMessages.Text = HttpUtility.HtmlEncode(_thread.Subject); + phLastPostingInThread.Visible = (_quoteMessageID<=0); + + bool userMayEditMemo = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.EditThreadMemo); + + // get quoted message if passed in. + if(_quoteMessageID>0) + { + // get message and insert it into the textbox including quote tags. + MessageEntity messageToQuote = MessageGuiHelper.GetMessage(_quoteMessageID); + if(messageToQuote != null) + { + // message found. + UserEntity quotedUser = UserGuiHelper.GetUser(messageToQuote.PostedByUserID); + if(quotedUser != null) + { + // user found. proceed + meMessageEditor.OriginalMessageText = TextParser.MakeStringQuoted(messageToQuote.MessageText, quotedUser.NickName); + } + } + } + else + { + // no quoted message. Load the last message from the active thread and display it in the form. This + // message entity has the poster user entity prefetched, together with the usertitle of the user. + MessageEntity lastMessageInThread = ThreadGuiHelper.GetLastMessageInThreadWithUserInfo(threadID); + if(lastMessageInThread!=null) + { + litMessageBody.Text = lastMessageInThread.MessageTextAsHTML; + lblPostingDate.Text = lastMessageInThread.PostingDate.ToString("dd-MMM-yyyy HH:mm:ss"); + if(lastMessageInThread.PostedByUser != null) + { + UserEntity messagePoster = lastMessageInThread.PostedByUser; + if(messagePoster.UserTitle != null) + { + lblUserTitleDescription.Text = messagePoster.UserTitle.UserTitleDescription; + } + lblLocation.Text = messagePoster.Location; + if(messagePoster.JoinDate.HasValue) + { + lblJoinDate.Text = messagePoster.JoinDate.Value.ToString("dd-MMM-yyyy HH:mm:ss"); + } + if(messagePoster.AmountOfPostings.HasValue) + { + lblAmountOfPostings.Text = messagePoster.AmountOfPostings.Value.ToString(); + } + if(messagePoster.SignatureAsHTML != null) + { + litSignature.Text = messagePoster.SignatureAsHTML; + } + lblNickname.Text = messagePoster.NickName; + } + } + } + + if((_thread.Memo.Length > 0) && userMayEditMemo) + { + // convert memo contents to HTML so it's displayed above the thread. + string parserLog, messageTextXml; + bool errorsOccured = false; + string memoAsHTML = TextParser.TransformUBBMessageStringToHTML(_thread.Memo, ApplicationAdapter.GetParserData(), out parserLog, out errorsOccured, out messageTextXml); + lblMemo.Text = memoAsHTML; + } + phMemo.Visible = userMayEditMemo; + } + } + + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + protected void PostMessageHandler(object sender, System.EventArgs e) + { + int userID = SessionAdapter.GetUserID(); + + // store the new message in the given thread + string mailTemplate = ApplicationAdapter.GetEmailTemplate(EmailTemplate.ThreadUpdatedNotification); + int messageID = ThreadManager.CreateNewMessageInThread(_thread.ThreadID, userID, meMessageEditor.MessageText, meMessageEditor.MessageTextHTML, + Request.UserHostAddress.ToString(), meMessageEditor.MessageTextXML, meMessageEditor.SubscribeToThread, + mailTemplate, ApplicationAdapter.GetEmailData(), CacheManager.GetSystemData().SendReplyNotifications); + + // invalidate forum RSS in cache + ApplicationAdapter.InvalidateCachedForumRSS(_thread.ForumID); + + // if auditing is required, we've to do this now. + if (SessionAdapter.CheckIfNeedsAuditing(AuditActions.AuditNewMessage)) + { + SecurityManager.AuditNewMessage(userID, messageID); + } + + // invalidate forum in asp.net cache + CacheManager.InvalidateCachedItem(CacheManager.ProduceCacheKey(CacheKeys.SingleForum, _thread.ForumID)); + + // all ok, redirect to message list + int startAtMessageIndex = ThreadGuiHelper.GetStartAtMessageForGivenMessageAndThread(_thread.ThreadID, messageID, SessionAdapter.GetUserDefaultNumberOfMessagesPerPage()); + if(meMessageEditor.AddAttachment) + { + // redirect to manage attachment form for this message + Response.Redirect(string.Format("Attachments.aspx?SourceType=1&MessageID={0}", messageID), true); + } + else + { + Response.Redirect(string.Format("Messages.aspx?ThreadID={0}&StartAtMessage={1}&#{2}", _thread.ThreadID, startAtMessageIndex, messageID), true); + } + } + + protected void CancelActionHandler(object sender, System.EventArgs e) + { + Response.Redirect("Messages.aspx?ThreadID=" + _thread.ThreadID + "&StartAtMessage=" + _startAtMessageIndex, true); + } + + + #region Class Property Declarations + /// + /// Gets the thread subject. + /// + /// The thread subject. + protected string ThreadSubject + { + get + { + string toReturn = string.Empty; + if(_thread != null) + { + toReturn = _thread.Subject; + } + return toReturn; + } + } + #endregion + } +} diff --git a/GUI/NewThread.aspx b/GUI/NewThread.aspx new file mode 100644 index 0000000..25d707e --- /dev/null +++ b/GUI/NewThread.aspx @@ -0,0 +1,48 @@ +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="MessageEditor" Src="MessageEditor.ascx"%> +<%@ Page language="c#" CodeFile="NewThread.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.NewThread" ValidateRequest="false" + Async="true"%> + + + + HnD::Create a new thread in Forum: <%=HttpUtility.HtmlEncode(base.ForumName)%> + + + + + + +
    + + + + + +
    +
    + You are here: Home > > > Add New Thread +

    +
    + + + + + +
    + +
    +
    +
    + + +
    + + + + diff --git a/GUI/NewThread.aspx.cs b/GUI/NewThread.aspx.cs new file mode 100644 index 0000000..bee1bc8 --- /dev/null +++ b/GUI/NewThread.aspx.cs @@ -0,0 +1,179 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file for the NewThread form. + /// + public partial class NewThread : System.Web.UI.Page + { + #region Class Member Declarations + private ForumEntity _forum; + private bool _userCanCreateNormalThreads, _userCanCreateStickyThreads; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + int forumID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ForumID"]); + _forum = CacheManager.GetForum(forumID); + if(_forum == null) + { + // not found + Response.Redirect("default.aspx", true); + } + + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(forumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx", true); + } + + _userCanCreateNormalThreads = SessionAdapter.CanPerformForumActionRight(forumID, ActionRights.AddNormalThread); + _userCanCreateStickyThreads = SessionAdapter.CanPerformForumActionRight(forumID, ActionRights.AddStickyThread); + + if(!(_userCanCreateNormalThreads || _userCanCreateStickyThreads)) + { + // doesn't have the right to add new threads to this forum. redirect + Response.Redirect("default.aspx", true); + } + + meMessageEditor.ShowAddAttachment = ((_forum.MaxNoOfAttachmentsPerMessage > 0) && + SessionAdapter.CanPerformForumActionRight(forumID, ActionRights.AddAttachment)); + + if(!String.IsNullOrEmpty(_forum.NewThreadWelcomeTextAsHTML)) + { + phWelcomeText.Visible = true; + litWelcomeText.Text = _forum.NewThreadWelcomeTextAsHTML; + } + + if(!Page.IsPostBack) + { + // fill the page's content + lnkThreads.Text = HttpUtility.HtmlEncode(_forum.ForumName); + lnkThreads.NavigateUrl += "?ForumID=" + forumID; + meMessageEditor.ForumName = _forum.ForumName; + meMessageEditor.ForumDescription = HttpUtility.HtmlEncode(_forum.ForumDescription); + meMessageEditor.CanBeSticky = _userCanCreateStickyThreads; + meMessageEditor.CanBeNormal = _userCanCreateNormalThreads; + meMessageEditor.IsThreadStart = true; + lblSectionName.Text = CacheManager.GetSectionName(_forum.SectionID); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + protected void PostMessageHandler(object sender, System.EventArgs e) + { + int userID = SessionAdapter.GetUserID(); + int messageID = 0; + // store the new message as a new thread in the current forum. + bool isSticky = meMessageEditor.IsSticky; + if(!_userCanCreateNormalThreads && _userCanCreateStickyThreads) + { + // always sticky + isSticky = true; + } + int threadID = ForumManager.CreateNewThreadInForum(_forum.ForumID, userID, meMessageEditor.NewThreadSubject, + meMessageEditor.MessageText, meMessageEditor.MessageTextHTML, isSticky, + Request.UserHostAddress.ToString(), _forum.DefaultSupportQueueID, meMessageEditor.SubscribeToThread, out messageID); + + // invalidate forum RSS in cache + ApplicationAdapter.InvalidateCachedForumRSS(_forum.ForumID); + + if (SessionAdapter.CheckIfNeedsAuditing(AuditActions.AuditNewThread)) + { + SecurityManager.AuditNewThread(userID, threadID); + } + + // invalidate Forum in ASP.NET cache + CacheManager.InvalidateCachedItem(CacheManager.ProduceCacheKey(CacheKeys.SingleForum, _forum.ForumID)); + + if(meMessageEditor.AddAttachment) + { + // go to attachment management. + Response.Redirect(string.Format("Attachments.aspx?SourceType=2&MessageID={0}", messageID), true); + } + else + { + // all ok, redirect to thread list + Response.Redirect("Threads.aspx?ForumID=" + _forum.ForumID, true); + } + } + + protected void CancelActionHandler(object sender, System.EventArgs e) + { + Response.Redirect("Threads.aspx?ForumID=" + _forum.ForumID, true); + } + + + #region Class Property Declarations + /// + /// Gets the name of the forum. + /// + /// The name of the forum. + protected string ForumName + { + get + { + string toReturn = string.Empty; + if(_forum != null) + { + toReturn = _forum.ForumName; + } + return toReturn; + } + } + #endregion + } +} diff --git a/GUI/PageLegend.ascx b/GUI/PageLegend.ascx new file mode 100644 index 0000000..3833cdc --- /dev/null +++ b/GUI/PageLegend.ascx @@ -0,0 +1,44 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeFile="PageLegend.ascx.cs" Inherits="SD.HnD.GUI.PageLegend" %> +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +  Legend: +
     No new messages since your last visit. New messages since your last visit.
     No new messages since your last visit, thread is locked / closed. New messages since your last visit, thread is locked / closed.
     No new messages since your last visit, thread is pinned / sticky. New messages since your last visit, thread is pinned / sticky.
     Thread is marked 'done' by thread starter or support team. Thread is active.
     
    diff --git a/GUI/PageLegend.ascx.cs b/GUI/PageLegend.ascx.cs new file mode 100644 index 0000000..dc178d5 --- /dev/null +++ b/GUI/PageLegend.ascx.cs @@ -0,0 +1,43 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file for the page legend control. + /// + public partial class PageLegend : System.Web.UI.UserControl + { + protected void Page_Load(object sender, EventArgs e) + { + + } + } +} \ No newline at end of file diff --git a/GUI/PageList.ascx b/GUI/PageList.ascx new file mode 100644 index 0000000..03d5433 --- /dev/null +++ b/GUI/PageList.ascx @@ -0,0 +1,15 @@ +<%@ Control Language="c#" AutoEventWireup="false" CodeFile="PageList.ascx.cs" Inherits="SD.HnD.GUI.PageList" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> + + Pages: + + + <%# (int)(Container.DataItem)%> + <%# (int)(Container.DataItem)%> + + + + , + + <%# (int)(Container.DataItem)%> + + diff --git a/GUI/PageList.ascx.cs b/GUI/PageList.ascx.cs new file mode 100644 index 0000000..f465cb5 --- /dev/null +++ b/GUI/PageList.ascx.cs @@ -0,0 +1,228 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using SD.HnD.BL; + +namespace SD.HnD.GUI +{ + using System; + using System.Data; + using System.Drawing; + using System.Web; + using System.Web.UI.WebControls; + using System.Web.UI.HtmlControls; + + /// + /// ASP.NET Usercontrol class which will display a list of pagelinks: Pages: 1, 2, 3, etc + /// + public abstract partial class PageList : System.Web.UI.UserControl + { + #region Class Member Declarations + private int _amountMessages, _amountPages, _startMessageNo, _threadID; + private bool _highLight, _useCommaAsSeparator, _isOnThreadsPage; + #endregion + + /// + /// Constructor + /// + /// + /// + private void Page_Load(object sender, System.EventArgs e) + { + int[] pageList = new int[_amountPages]; + + for(int i=0;i<_amountPages;i++) + { + pageList[i] = (i + 1); + } + + if(_isOnThreadsPage) + { + rptPageListThreads.Visible = true; + rptPageListThreads.DataSource = pageList; + rptPageListThreads.DataBind(); + } + else + { + rptPageListMessages.Visible = true; + rptPageListMessages.DataSource = pageList; + rptPageListMessages.DataBind(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.rptPageListMessages.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.rptPageListMessages_ItemDataBound); + this.rptPageListThreads.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.rptPageListThreads_ItemDataBound); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + /// + /// Event handler for the ItemDataBound event for the repeater control for the pagelist in the Messages page. In here the decision is made + /// if the current item will be a link (we're not on this page) or not (thus a label) + /// + /// + /// + private void rptPageListMessages_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + int currentPage = (_startMessageNo/maxAmountMessagesPerPage)+1; + if((currentPage) == (int)(e.Item.DataItem)) + { + // the current number emitted by the repeater is the page number we're on at the moment. + Label lblMessagePage = (Label)e.Item.FindControl("lblMessagesPage"); + lblMessagePage.Visible=true; + } + else + { + HyperLink lnkMessagePage = (HyperLink)e.Item.FindControl("lnkMessagesPage"); + lnkMessagePage.NavigateUrl += "?ThreadID=" + _threadID + "&StartAtMessage=" + + (((int)(e.Item.DataItem)-1)*maxAmountMessagesPerPage); + if(_highLight) + { + lnkMessagePage.NavigateUrl+="&HighLight=1"; + } + lnkMessagePage.Visible=true; + } + break; + } + } + + + /// + /// Event handler for the ItemDataBound event for the repeater control for the pagelist in the Threads page. In here the decision is made + /// if the current item will be a link (we're not on this page) or not (thus a label) + /// + /// + /// + private void rptPageListThreads_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + int currentPage = (_startMessageNo / maxAmountMessagesPerPage) + 1; + HyperLink lnkMessagePage = (HyperLink)e.Item.FindControl("lnkMessagesPage"); + lnkMessagePage.NavigateUrl += "?ThreadID=" + _threadID + "&StartAtMessage=" + + (((int)(e.Item.DataItem) - 1) * maxAmountMessagesPerPage); + if(_highLight) + { + lnkMessagePage.NavigateUrl += "&HighLight=1"; + } + break; + } + } + + + #region Class Property Definitions + /// + /// StartMessageNo property. Sets the startmessage number for the active page calculation. + /// + public int StartMessageNo + { + set { _startMessageNo = value; } + } + + /// + /// AmountMessages property. Calculates with this value the amount of pages. + /// + public int AmountMessages + { + + set + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + _amountMessages = value; + _amountPages=((_amountMessages-1)/maxAmountMessagesPerPage)+1; + } + } + + /// + /// ThreadID property, for link emitter + /// + public int ThreadID + { + set { _threadID = value; } + } + + /// + /// Gets or sets a value indicating whether [high light]. + /// + public bool HighLight + { + get { return _highLight;} + set { _highLight = value;} + } + + /// + /// Gets / sets UseCommaAsSeparator + /// + public bool UseCommaAsSeparator + { + get + { + return _useCommaAsSeparator; + } + set + { + _useCommaAsSeparator = value; + } + } + + /// + /// Gets / sets onThreadsPage + /// + public bool IsOnThreadsPage + { + get + { + return _isOnThreadsPage; + } + set + { + _isOnThreadsPage = value; + } + } + + #endregion + } +} diff --git a/GUI/PrintMessages.aspx b/GUI/PrintMessages.aspx new file mode 100644 index 0000000..41ded86 --- /dev/null +++ b/GUI/PrintMessages.aspx @@ -0,0 +1,85 @@ +<%@ Page language="c#" CodeFile="PrintMessages.aspx.cs" AutoEventWireup="true" Inherits="SD.HnD.GUI.PrintMessages"%> +<%@ Import namespace="System.Web" %> +<%@ Import namespace="System.Data" %> +<%@ Import Namespace="SD.HnD.GUI" %> + + + HnD::List all messages of thread: <%=HttpUtility.HtmlEncode(base.ThreadSubject)%> + + + +
    +

    Forum:  

    +

    Thread:  <%=HttpUtility.HtmlEncode(base.ThreadSubject)%>

    +
    + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + + + +
    + <%# Eval("NickName")%> (<%# Eval("UserTitleDescription")%>)   + Posted on: <%# ((DateTime)Eval("PostingDate")).ToString(@"dd-MMM-yyyy HH:mm:ss")%>. Posted from IP: +
    + <%# Eval("MessageTextAsHTML")%> +
    +
    +
    + + + + +
    + + + + + + + +
    + <%# Eval("NickName")%> (<%# Eval("UserTitleDescription")%>)   + Posted on: <%# ((DateTime)Eval("PostingDate")).ToString(@"dd-MMM-yyyy HH:mm:ss")%>. Posted from IP: +
    + <%# Eval("MessageTextAsHTML")%> +

    +
    +
    +
    + +
    +
    +
    + + diff --git a/GUI/PrintMessages.aspx.cs b/GUI/PrintMessages.aspx.cs new file mode 100644 index 0000000..8574772 --- /dev/null +++ b/GUI/PrintMessages.aspx.cs @@ -0,0 +1,161 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.DAL.CollectionClasses; +using System.Globalization; +using SD.HnD.DAL.TypedListClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind class for Messages.aspx, which renders a page of messages in a given thread. + /// + public partial class PrintMessages : System.Web.UI.Page + { + #region Class Member declarations + private ThreadEntity _thread; + private bool _showIPAddresses; + #endregion + + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int threadID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ThreadID"]); + _thread = ThreadGuiHelper.GetThread(threadID); + if(_thread == null) + { + // not found, return to start page + Response.Redirect("default.aspx"); + } + + // Check credentials + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx"); + } + + // show user IP addresses if the user has system admin rights, security admin rights or user admin rights. + _showIPAddresses = (SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement) || + SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement) || + SessionAdapter.HasSystemActionRight(ActionRights.UserManagement)); + // Get the forum entity related to the thread. Use BL class. We could have used Lazy loading, though for the sake of separation, we'll + // call into the BL class. + ForumEntity forum = CacheManager.GetForum(_thread.ForumID); + if(forum == null) + { + // not found, orphaned thread, return to default page. + Response.Redirect("default.aspx"); + } + + // check if the user can view this thread. If not, don't continue. + if((_thread.StartedByUserID != SessionAdapter.GetUserID()) && + !SessionAdapter.CanPerformForumActionRight(_thread.ForumID, ActionRights.ViewNormalThreadsStartedByOthers) && + !_thread.IsSticky) + { + // can't view this thread, it isn't visible to the user + Response.Redirect("default.aspx", true); + } + + lblForumName_Header.Text = forum.ForumName; + + if(!Page.IsPostBack) + { + bool threadStartedByCurrentUser = (_thread.StartedByUserID == SessionAdapter.GetUserID()); + // Get messages and bind it to the repeater control. Use the startmessage to get only the message visible on the current page. + MessagesInThreadTypedList messages = ThreadGuiHelper.GetAllMessagesInThreadAsTypedList(threadID, 0, 0); + rptMessages.DataSource = messages; + rptMessages.DataBind(); + } + } + + #region Class Property Declarations + /// + /// Gets the thread subject. + /// + /// The thread subject. + protected string ThreadSubject + { + get + { + if(_thread != null) + { + return _thread.Subject; + } + else + { + return string.Empty; + } + } + } + + /// + /// Gets the thread ID. + /// + /// The thread ID. + protected int ThreadID + { + get + { + if(_thread != null) + { + return _thread.ThreadID; + } + else + { + return 0; + } + } + } + + /// + /// Gets a value indicating whether IP addresses should be shown. Used by the HTML code + /// + protected bool ShowIPAddresses + { + get { return _showIPAddresses; } + } + #endregion + + private void Page_PreInit(object sender, EventArgs e) + { + // switch off theming as the EnableTheming option on the page level doesn't work + Page.Theme = ""; + } + } +} diff --git a/GUI/Profile.aspx b/GUI/Profile.aspx new file mode 100644 index 0000000..706ef62 --- /dev/null +++ b/GUI/Profile.aspx @@ -0,0 +1,194 @@ +<%@ Page language="c#" CodeFile="Profile.aspx.cs" AutoEventWireup="true" Inherits="SD.HnD.GUI._Profile" ValidateRequest="false" %> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register Src="Footer.ascx" TagName="PageFooter" TagPrefix="HnD" %> +<%@ Register TagPrefix="HnD" TagName="PageList" Src="PageList.ascx"%> +<%@ Import namespace="System.Web" %> +<%@ Import Namespace="System.Globalization" %> +<%@ Import Namespace="SD.HnD.GUI" %> + + + + HnD::Show User Profile + + + + + +
    +
    + + + + +
    +

    User profile

    + The user profile below contains information which is filled in by the user. It is against the law to + collect any information from this page in any form whatsoever without prior written permission of the + user who owns this account. +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nickname
    Email address + Not visible. + +
    User icon +
    + +
    Date of birth
    Occupation
    Location
    Website + +
    Signature
    User title
    Registered on
    Number of posts
    IP Address
    Last visit date
    +
    +
    + Close window +
    +
    +
    +
    +
    + + + + + + + + + +
    + Last 25 threads this user participated in +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     Thread subjectRepliesViewsLast post
    + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +    
    +
    + Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    +
    <%# (int)Eval("AmountMessages") - 1%><%# Eval("NumberOfViews")%> +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On:
    +
    + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +    
    +
    + Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    +
    <%# (int)Eval("AmountMessages") - 1%><%# Eval("NumberOfViews")%> +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On:
    +
    + +
    + + + + + + diff --git a/GUI/Profile.aspx.cs b/GUI/Profile.aspx.cs new file mode 100644 index 0000000..831cad6 --- /dev/null +++ b/GUI/Profile.aspx.cs @@ -0,0 +1,202 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// Code behind of the profile viewer form. + /// + public partial class _Profile : System.Web.UI.Page + { + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int userID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["UserID"]); + + if(!Page.IsPostBack) + { + UserEntity user = UserGuiHelper.GetUserWithTitleDescription(userID); + if(user == null) + { + // not found + Response.Redirect("default.aspx", true); + } + + // fill in the content. The user's data is already html encoded (it's stored htmlencoded in the db), so + // we don't need to worry to htmlencode it before it's displayed in the form. + lblNickName.Text = user.NickName; + bool emailAddressIsPublic = false; + if(user.EmailAddressIsPublic.HasValue) + { + emailAddressIsPublic = user.EmailAddressIsPublic.Value; + } + if(emailAddressIsPublic||(SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement))) + { + lblEmailAddressNotPublicTxt.Visible=false; + lnkEmailAddress.Visible=true; + lnkEmailAddress.NavigateUrl="mailto:" + user.EmailAddress; + lnkEmailAddress.Text = user.EmailAddress; + } + else + { + lblEmailAddressNotPublicTxt.Visible=true; + } + + // view admin section if the user has system admin rights, security management rights, or user management rights. + phAdminSection.Visible = (SessionAdapter.HasSystemActionRight(ActionRights.SystemManagement) || + SessionAdapter.HasSystemActionRight(ActionRights.SecurityManagement) || + SessionAdapter.HasSystemActionRight(ActionRights.UserManagement)); + + if(!string.IsNullOrEmpty(user.IconURL)) + { + // show icon + string sURL = "http://" + user.IconURL; + imgIcon.ImageUrl = sURL; + imgIcon.Visible=true; + lblIconURL.Text = sURL; + } + + if(user.LastVisitedDate.HasValue) + { + lblLastVisitDate.Text = user.LastVisitedDate.Value.ToString("dd-MMM-yyy HH:mm.ss"); + } + else + { + lblLastVisitDate.Text = "Unknown (tracked by cookie)"; + } + + if(user.DateOfBirth.HasValue) + { + lblDateOfBirth.Text = user.DateOfBirth.Value.ToString("dd-MMM-yyyy"); + } + lblOccupation.Text = user.Occupation; + lblLocation.Text = user.Location; + + if(!string.IsNullOrEmpty(user.Website)) + { + string sURL = "http://" + user.Website; + lnkWebsite.Text = sURL; + lnkWebsite.NavigateUrl = sURL; + lnkWebsite.Visible=true; + } + + lblSignature.Text = user.SignatureAsHTML; + + lblRegisteredOn.Text = user.JoinDate.Value.ToString("dd-MMM-yyyy HH:mm:ss"); + lblAmountOfPosts.Text = user.AmountOfPostings.ToString(); + lblUserTitle.Text = user.UserTitle.UserTitleDescription; + lblIpAddress.Text = user.IPNumber; + + // get the last 25 threads. + DataView lastThreads = UserGuiHelper.GetLastThreadsForUserAsDataView(SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum), userID, + SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), SessionAdapter.GetUserID(), 25); + rpThreads.DataSource = lastThreads; + rpThreads.DataBind(); + } + } + + + /// + /// Event handler which will be called every time a row in the Repeater rpThreads is bound to a row in the view. + /// + /// + /// + protected void rpThreads_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + // Thread has always a last posting date: a thread has at least 1 posting. + DateTime threadLastPostingDate = (DateTime)(((DataRowView)e.Item.DataItem)["ThreadLastPostingDate"]); + DateTime lastVisitDate = SessionAdapter.GetLastVisitDate(); + bool isSticky = (bool)(((DataRowView)e.Item.DataItem)["IsSticky"]); + bool isClosed = (bool)(((DataRowView)e.Item.DataItem)["IsClosed"]); + + // date is not 0, check if the date is > than the date in the session variable. If so, the posting is newer and we + // should visualize the New Messages image, otherwise the No new Messages image. Also take into account + // the type of the thread: sticky, closed or normal. + System.Web.UI.WebControls.Image imgIconPosts; + + if(threadLastPostingDate > lastVisitDate) + { + // there are new messages since last visit + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPosts"); + } + } + } + else + { + // no new messages + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPosts"); + } + } + } + imgIconPosts.Visible = true; + break; + } + } + } +} diff --git a/GUI/Register.aspx b/GUI/Register.aspx new file mode 100644 index 0000000..9b588c3 --- /dev/null +++ b/GUI/Register.aspx @@ -0,0 +1,162 @@ +<%@ Page language="c#" CodeFile="Register.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Register" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> + + + + HnD::Register as new user + + + + + + +
    + + +
    +
    + + + + + +
    +

    Register as a new user.

    +

    + Below you can enter your information to register so you will be allowed to participate in the + discussions helt in the various forums. When registering, you agree to be bound to the registration terms of this site and + which apply to all forums. These terms can be found here. If you do not + agree with these rules, you should not register. +

    +

    + No information will be disclosed to other parties than the forumsystem itself. You decide which information you + want to enter in the non-mandatory fields. The email-address you enter is used to send you a new password, when + you might forget it and can be made hidden for visitors of the forums. The email address is also used for sending you + notifications if you subscribe to thread notifications. +

    +

    + Please, don't forget to read the registration terms. +

    +
    +
    + + + + +
    + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Your profile
    Registration information. Fields marked with a '*' are mandatory.
    Nickname * + + + Nickname already exists. +
    PasswordYour initial password will be randomly generated and mailed to the address you specify at + Email address below. +
    Your IP number
    Emailaddress * +   + + +

    Personal information, which should tell something about you.
    User icon URL
    + (Only 60x60 .jpg and .gif are accepted) +
    + http://
    + +
    Date of birth
    + Format: mm/dd/yyyy
    + + +
    Occupation
    Location
    + f.e.: city, country
    Websitehttp://
    + +
    Signature
    + You can use several UBB Tags in your signature. Maximum length is 250 characters.

    Preferences.
    Email address is hidden
    Notify me of thread replies
    + Overridable per-thread +
    Messages per page + +
      +
    + +
    +
    +
    +
    +
    + + + + diff --git a/GUI/Register.aspx.cs b/GUI/Register.aspx.cs new file mode 100644 index 0000000..9de8d6b --- /dev/null +++ b/GUI/Register.aspx.cs @@ -0,0 +1,167 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Globalization; +using SD.HnD.BL; +using SD.HnD.Utility; +using System.IO; + +namespace SD.HnD.GUI +{ + /// + /// Code behind for the Register form. + /// + public partial class Register : System.Web.UI.Page + { + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + if(!Page.IsPostBack) + { + // Get the user's IP number + lblIPNumber.Text = Request.UserHostAddress.ToString(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnRegister.ServerClick += new System.EventHandler(this.btnRegister_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + + /// + /// Handles the click event on the register button. + /// + /// + /// + private void btnRegister_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + string nickName = HttpUtility.HtmlEncode(tbxNickName.Value); + + // check if the nickname is already taken. + bool nickNameAlreadyExists = UserGuiHelper.CheckIfNickNameExists(nickName); + if(nickNameAlreadyExists) + { + // already exists + lblNickNameError.Visible=true; + } + else + { + // doesn't exist. Form is valid, so write the data into the database. + DateTime? dateOfBirth = null; + string emailAddress = string.Empty; + bool emailAddressIsPublic = false; + string iconURL = string.Empty; + string ipNumber = string.Empty; + string location = string.Empty; + string occupation = string.Empty; + string password = string.Empty; + string signature = string.Empty; + string website = string.Empty; + bool autoSubscribeThreads = true; + short defaultMessagesPerPage = 10; + + if(tbxDateOfBirth.Value.Length > 0) + { + try + { + dateOfBirth = System.DateTime.Parse(tbxDateOfBirth.Value, CultureInfo.InvariantCulture.DateTimeFormat); + } + catch(FormatException) + { + // format exception, date invalid, ignore, will resolve to the default : null + } + } + + emailAddress = tbxEmailAddress.Value; + emailAddressIsPublic = !chkEmailAddressIsHidden.Checked; + if(tbxIconURL.Value.Length > 0) + { + iconURL = tbxIconURL.Value; + } + ipNumber = lblIPNumber.Text; + if(tbxLocation.Value.Length > 0) + { + location = tbxLocation.Value; + } + if(tbxOccupation.Value.Length > 0) + { + occupation = tbxOccupation.Value; + } + + if(tbxSignature.Value.Length > 0) + { + signature = tbxSignature.Value; + } + if(tbxWebsite.Value.Length > 0) + { + website = tbxWebsite.Value; + } + + //Preferences + autoSubscribeThreads = chkAutoSubscribeToThread.Checked; + if (tbxDefaultNumberOfMessagesPerPage.Value.Length > 0) + { + defaultMessagesPerPage = HnDGeneralUtils.TryConvertToShort(tbxDefaultNumberOfMessagesPerPage.Value); + } + + // add it + string mailTemplate = ApplicationAdapter.GetEmailTemplate(EmailTemplate.RegistrationReply); + int userID = UserManager.RegisterNewUser(nickName, dateOfBirth, emailAddress, emailAddressIsPublic, iconURL, ipNumber, location, + occupation, signature, website, mailTemplate, ApplicationAdapter.GetEmailData(), ApplicationAdapter.GetParserData(), autoSubscribeThreads, defaultMessagesPerPage); + + Response.Redirect("registrationsuccessful.aspx", true); + } + } + } + } +} diff --git a/GUI/RegistrationRules.aspx b/GUI/RegistrationRules.aspx new file mode 100644 index 0000000..d54995c --- /dev/null +++ b/GUI/RegistrationRules.aspx @@ -0,0 +1,68 @@ +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> +<%@ Page language="c#" CodeFile="RegistrationRules.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.RegistrationRules" %> + + + + HnD::Registration terms + + + + + + + +
    +

    + + + + +
    +

    Registration terms

    +

    + While the administrators and moderators of this forum will attempt to remove or + edit any generally objectionable material as quickly as possible, it is + impossible to review every message. Therefore you acknowledge that all posts + made to these forums express the views and opinions of the author and not the + administrators, moderators or webmaster (except for posts by these people) and + hence will not be held liable. +

    +

    + You agree not to post any abusive, obscene, vulgar, slanderous, hateful, threatening, + sexually-orientated or any other material, including links to pirated software or related to + pirated software, that may violate any applicable laws. + Doing so may lead to you being immediately and permanently banned (and your service provider being + informed). The IP address of all people posting in forums on this forum system is logged to aid in + enforcing these conditions. +

    +

    + You agree that the webmaster, administrator and moderators of this + forum system have the right to remove, edit, move or close any topic at any time should + they see fit. As a user you agree to any information you have entered in the registration form, or + in the profile editing form, being stored in a database. While this information will not be + disclosed to any third party without your consent the webmaster, administrator and moderators + cannot be held responsible for any hacking attempt that may lead to the data + being compromised. +

    +

    + This forum system uses cookies to store information on your local computer. + These cookies do not contain any of the information you have entered when you registered nor when you edited + your profile or any information related to your postings on this board, they serve only to improve your + viewing pleasure. The email address is used only for sending you your initial password (and for sending new + passwords should you forget your current one) as well as notification emails of new posts in threads, if you've + subscribed to these threads. +

    +

    + By registering at this forum system, you agree with these registration terms. +

    +
    + Close window +
    +
    +
    +
    + + + + diff --git a/GUI/RegistrationRules.aspx.cs b/GUI/RegistrationRules.aspx.cs new file mode 100644 index 0000000..2609120 --- /dev/null +++ b/GUI/RegistrationRules.aspx.cs @@ -0,0 +1,63 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI +{ + /// + /// Empty code behind for the RegistrationRules page. + /// + public partial class RegistrationRules : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // Put user code to initialize the page here + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/GUI/RegistrationSuccessful.aspx b/GUI/RegistrationSuccessful.aspx new file mode 100644 index 0000000..66328d1 --- /dev/null +++ b/GUI/RegistrationSuccessful.aspx @@ -0,0 +1,32 @@ +<%@ Page language="c#" CodeFile="RegistrationSuccessful.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.RegistrationSuccessful" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> + + + + HnD::Registration Successful + + + +
    + + +
    +
    + + + + +
    +

    Registration was successful!

    + You'll receive an email with your password a.s.a.p. Use that password to login, by clicking + here. You can then change your password by editing your profile. +

    +
    +
    +
    + + + + + diff --git a/GUI/RegistrationSuccessful.aspx.cs b/GUI/RegistrationSuccessful.aspx.cs new file mode 100644 index 0000000..3378f63 --- /dev/null +++ b/GUI/RegistrationSuccessful.aspx.cs @@ -0,0 +1,64 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI +{ + /// + /// Empty code behind for the RegistrationSuccessful form. + /// + public partial class RegistrationSuccessful : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // Put user code to initialize the page here + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + } +} diff --git a/GUI/ResetPassword.aspx b/GUI/ResetPassword.aspx new file mode 100644 index 0000000..a731399 --- /dev/null +++ b/GUI/ResetPassword.aspx @@ -0,0 +1,66 @@ +<%@ Page language="c#" CodeFile="ResetPassword.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.ResetPassword" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> + + + + HnD::Reset Password + + + + + + + + +
    +
    +
    + + + + +
    + Reset your password

    + Please specify your nickname and emailaddress to reset your password. Your new password + will be mailed to the emailaddress registered with the nickname you specify. The emailaddress you specify + below has to be the same emailaddress otherwise the system will not reset your password.
    + + + + + + + + + + + + + + +
     
    Nickname   +
    Emailaddress   +
      +
    + +

    +
    +
    + + + + +
    + +
    +
    + + + + diff --git a/GUI/ResetPassword.aspx.cs b/GUI/ResetPassword.aspx.cs new file mode 100644 index 0000000..841a1d7 --- /dev/null +++ b/GUI/ResetPassword.aspx.cs @@ -0,0 +1,100 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using System.IO; + +namespace SD.HnD.GUI +{ + /// + /// Code behind for the ResetPassword form. + /// + public partial class ResetPassword : System.Web.UI.Page + { + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnResetPassword.ServerClick += new System.EventHandler(this.btnResetPassword_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnResetPassword_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + try + { + // user has filled in all fields, let's reset the password. + string mailTemplate = ApplicationAdapter.GetEmailTemplate(EmailTemplate.RegistrationReply); + bool result = UserManager.ResetPassword(tbxNickName.Value, tbxEmailAddress.Value, mailTemplate, ApplicationAdapter.GetEmailData()); + if(result) + { + // ok + Response.Redirect("ResetPasswordSuccessful.aspx",true); + } + // not ok + lblErrorMessage.Text = "Something went wrong with the reset action. Please try again."; + } + catch(NickNameNotFoundException ex) + { + lblErrorMessage.Text = ex.Message; + } + catch(EmailAddressDoesntMatchException ex) + { + lblErrorMessage.Text = ex.Message; + } + // bubble up others. + } + } + } +} diff --git a/GUI/ResetPasswordSuccessful.aspx b/GUI/ResetPasswordSuccessful.aspx new file mode 100644 index 0000000..88c0c30 --- /dev/null +++ b/GUI/ResetPasswordSuccessful.aspx @@ -0,0 +1,30 @@ +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="HeaderRestrictedMenu.ascx"%> +<%@ Page language="c#" CodeFile="ResetPasswordSuccessful.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.ResetPasswordSuccessful" %> + + + + HnD::Reset of password Successful + + + + + +
    +
    + + + + +
    +

    Reset of your password was successful!

    + You'll receive an email with your new password a.s.a.p. Use that password to login, by clicking + here. You can then change your new password by editing your profile. +

    +
    +
    +
    + + + + diff --git a/GUI/ResetPasswordSuccessful.aspx.cs b/GUI/ResetPasswordSuccessful.aspx.cs new file mode 100644 index 0000000..6a1fc3e --- /dev/null +++ b/GUI/ResetPasswordSuccessful.aspx.cs @@ -0,0 +1,64 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI +{ + /// + /// Code behind of the ResetPasswordSuccessful form. + /// + public partial class ResetPasswordSuccessful : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // Put user code to initialize the page here + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + } +} diff --git a/GUI/Rssforum.aspx b/GUI/Rssforum.aspx new file mode 100644 index 0000000..93652fa --- /dev/null +++ b/GUI/Rssforum.aspx @@ -0,0 +1,24 @@ +<%@ Page language="c#" CodeFile="Rssforum.aspx.cs" ContentType="text/xml" AutoEventWireup="true" Inherits="SD.HnD.GUI.Rssforum" %> + + + <%=HttpUtility.HtmlEncode(base.SiteName)%> <%=HttpUtility.HtmlEncode(base.ForumName)%> feed + <%=HttpUtility.HtmlEncode(base.ForumURL)%> + This is the RSS feed for the forum <%=HttpUtility.HtmlEncode(base.ForumName)%> on the <%=HttpUtility.HtmlEncode(base.SiteName)%> forum system. + 30 + en-us + + + + + <asp:literal Runat="server" ID="title" /> + + + + + + + + + + + diff --git a/GUI/Rssforum.aspx.cs b/GUI/Rssforum.aspx.cs new file mode 100644 index 0000000..3e2fcbe --- /dev/null +++ b/GUI/Rssforum.aspx.cs @@ -0,0 +1,186 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.DAL.TypedListClasses; +using SD.HnD.Utility; +using SD.HnD.DAL.EntityClasses; + +namespace SD.HnD.GUI +{ + /// + /// Produces an RSS 2.0 feed for the forum specified. + /// + public partial class Rssforum : System.Web.UI.Page + { + #region Class Member Declarations + private string _siteName, _forumURL; + private ForumEntity _forum; + #endregion + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + _siteName = HttpUtility.HtmlEncode(ApplicationAdapter.GetSiteName()); + + int forumID = HnDGeneralUtils.TryConvertToInt(Request.QueryString["ForumID"]); + _forum = CacheManager.GetForum(forumID); + if((_forum != null) && _forum.HasRSSFeed) + { + _forumURL = "http://" + Request.Url.Host + ApplicationAdapter.GetVirtualRoot() + String.Format(@"Threads.aspx?ForumID={0}", forumID); + + // get the messages + ForumMessagesTypedList messages = ForumGuiHelper.GetLastPostedMessagesInForum(10, forumID); + rptRSS.DataSource = messages; + rptRSS.DataBind(); + + Response.Cache.SetExpires(DateTime.Now.AddDays(7)); + Response.Cache.SetCacheability(HttpCacheability.Public); + Response.Cache.SetValidUntilExpires(true); + Response.Cache.VaryByParams["ForumID"] = true; + Response.Cache.AddValidationCallback(new HttpCacheValidateHandler(Validate), null); + } + } + + private void Page_PreInit(object sender, EventArgs e) + { + // switch off theming as the EnableTheming option on the page level doesn't work due to a bug in ASP.NET 2.0 + Page.Theme = ""; + } + + + /// + /// Cache validator routine. + /// + /// + /// + /// + public void Validate(HttpContext context, Object data, ref HttpValidationStatus status) + { + // get flag + Hashtable cacheFlags = ApplicationAdapter.GetCacheFlags(); + + bool isValid = true; + if(cacheFlags.ContainsKey(_forum.ForumID)) + { + isValid = (bool)cacheFlags[_forum.ForumID]; + } + + if(isValid) + { + status = HttpValidationStatus.Valid; + } + else + { + status = HttpValidationStatus.Invalid; + } + } + + + protected void rptRSS_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + DataRowView currentRow = (DataRowView)e.Item.DataItem; + string nickName = currentRow["NickName"].ToString(); + string message = currentRow["MessageTextAsHTML"].ToString(); + string subject = currentRow["Subject"].ToString(); + Literal title = (Literal)e.Item.FindControl("title"); + title.Text = HttpUtility.HtmlEncode(String.Format("{0} by {1}", subject, nickName)); + + Literal description = (Literal)e.Item.FindControl("description"); + description.Text = HttpUtility.HtmlEncode(message); + + Literal link = (Literal)e.Item.FindControl("itemLink"); + int threadID = (int)currentRow["ThreadID"]; + int messageID = (int)currentRow["MessageID"]; + int startAtMessage = ThreadGuiHelper.GetStartAtMessageForGivenMessageAndThread(threadID, messageID, ApplicationAdapter.GetMaxAmountMessagesPerPage()); + link.Text = HttpUtility.HtmlEncode("http://" + Request.Url.Host + ApplicationAdapter.GetVirtualRoot() + String.Format(@"Messages.aspx?ThreadID=" + threadID + "&StartAtMessage=" + startAtMessage + "#" + messageID)); + + Literal permaLink = (Literal)e.Item.FindControl("permaLink"); + permaLink.Text = link.Text; + + Literal pubDate = (Literal)e.Item.FindControl("pubDate"); + pubDate.Text = String.Format("{0:R}", ((DateTime)currentRow["PostingDate"]).AddHours(-2)); + + Literal author = (Literal)e.Item.FindControl("author"); + author.Text = nickName; + + Literal category = (Literal)e.Item.FindControl("threadName"); + category.Text = HttpUtility.HtmlEncode(subject); + break; + } + } + + + #region Class Property Declarations + /// + /// Gets the name of the site. + /// + /// The name of the site. + protected string SiteName + { + get { return _siteName; } + } + + /// + /// Gets the forum URL. + /// + /// The forum URL. + protected string ForumURL + { + get { return _forumURL; } + } + + /// + /// Gets the name of the forum. + /// + /// The name of the forum. + protected string ForumName + { + get + { + string toReturn = string.Empty; + if(_forum != null) + { + toReturn = _forum.ForumName; + } + return toReturn; + } + } + #endregion + } +} diff --git a/GUI/Search.aspx b/GUI/Search.aspx new file mode 100644 index 0000000..7428a26 --- /dev/null +++ b/GUI/Search.aspx @@ -0,0 +1,146 @@ +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Page language="c#" CodeFile="Search.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Search" ValidateRequest="false"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Import namespace="System.Data" %> + + + + HnD::Search + + + + + + +
    + + +
    +

    + + + + +
    + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Your search query
    Search string  +   + +
    Element to search  + + Message text + Thread subject + Message text and thread subject + +
    Forums to search in 
    + (Hold Ctrl to select more) 
    + +
    Sort by  + + Last post date, descending + Last post date, ascending + Forum, ascending + Forum, descending + Thread subject, ascending + Thread subject, descending +
    + And
    + + Last post date, descending + Last post date, ascending + Forum, ascending + Forum, descending + Thread subject, ascending + Thread subject, descending + +
      +
    + +
    +
    +

    + + + + +
    + Search. +

    + Above you can specify your search query, which element to search and in which forums you want to search. If you do not select a + forum, all forums are searched. You can specify 'AND', 'OR', 'AND NOT' and 'OR NOT' to specify your query arguments. + If no operator is specified, AND is assumed, so you don't have to + specify it explicitly. Specifying 'OR' will search for either of the two terms it's placed in between.
    + This searchengine uses SqlServer full text search together with LLBLGen Pro code to search through the + posts on this forum, using CONTAINS queries. The forum search engine therefore accepts + queries which are valid CONTAINS queries. Below is a brief help on the basic syntaxis of CONTAINS queries. You can also consult the CONTAINS + reference documentation in SqlServer Books Online, if you have access to that documentation, for the more advanced elements of the + syntaxis of CONTAINS queries. +

    + The search engine will at most return 500 hits. If you receive 500 hits, please refine your query. A search in both message text and thread subject + will likely result in more results and this search is also slower. +

    + Query syntaxis
    + You can use exact index searching by specifying the terms you're looking for, like Entity or Prefetch, which will exactly match with + Entity and Prefetch. If you want to use wild-cards, you can. For example Entity* will match with Entity but also with + EntityClass, EntityMethod but not with MyEntity. To find MyEntity as well, specify *Entity*.
    + You can also use phrases, to search for "Entity Collection" for example. Simply enclose any text that you want to search for which contains + spaces with double quotes. To search for a word near another word, you can use the keyword 'NEAR': Entity NEAR collection, which search for 'Entity' + and 'Collection', and will favor messages which contain these words closer together over messages which have these words far apart from eachother. +

    + The search results consists of links to threads with messages matching the search query. All threads open in a new window. At most 500 threads + are made available to you in the search result page. In the case of a lot of search results, you're adviced to specify more search terms to narrow + down the resultset. The search is case-insensitive. +

    + Examples:
    + Prefetch AND Path (which results in all messages with 'Prefetch' and 'Path') Equals to: Prefetch Path
    + Prefetch OR Path (which results in all messages with 'Prefetch' or 'Path' or both)
    + Prefetch Path* (which results in all messages with 'Prefetch' and all known words starting with 'Path')
    + Entity Prefetch OR Path (which results in all messages with 'Entity', and either 'Prefetch' or 'Path' or both)
    + "Entity Collection" (which results in all messages with 'Entity Collection', including the space)
    +
    + Note: The search engine uses a list of words which are ignored. Please click + here to check this list. If you perform a search with a reserved word and the AND operator, + no rows are returned, as it will not return in any hits. +

    +
    +
    +
    + + + + diff --git a/GUI/Search.aspx.cs b/GUI/Search.aspx.cs new file mode 100644 index 0000000..b0b8336 --- /dev/null +++ b/GUI/Search.aspx.cs @@ -0,0 +1,163 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; + +using SD.HnD.DAL.TypedListClasses; + +namespace SD.HnD.GUI +{ + /// + /// Code behind of the search form + /// + public partial class Search : System.Web.UI.Page + { + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + // this is necessary so the 'clever' IE will also understand what to do: the enter key will then submit the form. + this.ClientScript.RegisterHiddenField("__EVENTTARGET", "btnSearch"); + + if(!Page.IsPostBack) + { + // clear tmp results in session + SessionAdapter.AddSearchTermsAndResults(string.Empty, null); + + // Read all the current existing forums and their section names. + ForumsWithSectionNameTypedList forumsWithSectionName = ForumGuiHelper.GetAllForumsWithSectionNames(); + + // Get a list of Forum IDs to which the user has access right. + List accessableForums = SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum); + + foreach(ForumsWithSectionNameRow currentRow in forumsWithSectionName) + { + // filter out forums the user doesn't have access rights for. + if(accessableForums.Contains(currentRow.ForumID)) + { + // forum is accessable to the user + ListItem newItem = new ListItem(String.Format("{0} - {1}", currentRow.SectionName, currentRow.ForumName), currentRow.ForumID.ToString()); + newItem.Selected=true; + lbxForums.Items.Add(newItem); + } + } + + // make listbox as high as # of forums, with a maximum of 15 and a minimum of 8 + if(lbxForums.Items.Count <= 15) + { + if(lbxForums.Items.Count > 8) + { + lbxForums.Rows = lbxForums.Items.Count; + } + else + { + lbxForums.Rows = 8; + } + } + else + { + lbxForums.Rows = 15; + } + + lblNumberOfPosts.Text = MessageGuiHelper.GetTotalNumberOfMessages().ToString(); + } + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSearch.ServerClick += new System.EventHandler(this.btnSearch_ServerClick); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + private void btnSearch_ServerClick(object sender, System.EventArgs e) + { + if(Page.IsValid) + { + // grab forum id's + List forumIDs = new List(); + for (int i = 0; i < lbxForums.Items.Count; i++) + { + if(lbxForums.Items[i].Selected) + { + forumIDs.Add(Convert.ToInt32(lbxForums.Items[i].Value)); + } + } + + if(forumIDs.Count<=0) + { + // no forums selected, add all of them + for (int i = 0; i < lbxForums.Items.Count; i++) + { + forumIDs.Add(Convert.ToInt32(lbxForums.Items[i].Value)); + } + } + + SearchResultsOrderSetting orderFirstElement = (SearchResultsOrderSetting)cbxSortByFirstElement.SelectedIndex; + SearchResultsOrderSetting orderSecondElement = (SearchResultsOrderSetting)cbxSortBySecondElement.SelectedIndex; + + SearchTarget targetToSearch = (SearchTarget)cbxElementToSearch.SelectedIndex; + + string searchTerms = tbxSearchString.Value; + if(searchTerms.Length>1024) + { + searchTerms = searchTerms.Substring(0, 1024); + } + + // Use Full text search variant. + SearchResultTypedList results = BL.Searcher.DoSearch(searchTerms, forumIDs, orderFirstElement, orderSecondElement, + SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), SessionAdapter.GetUserID(), targetToSearch); + + // store results in session. + SessionAdapter.AddSearchTermsAndResults(searchTerms, results); + // view results. + Response.Redirect("SearchResults.aspx?Page=1", true); + } + } + } +} diff --git a/GUI/SearchResultPageList.ascx b/GUI/SearchResultPageList.ascx new file mode 100644 index 0000000..6131ec3 --- /dev/null +++ b/GUI/SearchResultPageList.ascx @@ -0,0 +1,9 @@ +<%@ Control Language="c#" AutoEventWireup="false" CodeFile="SearchResultPageList.ascx.cs" Inherits="SD.HnD.GUI.SearchResultPageList" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> + + Pages: + + + <%# (int)(Container.DataItem)%> + <%# (int)(Container.DataItem)%> + + diff --git a/GUI/SearchResultPageList.ascx.cs b/GUI/SearchResultPageList.ascx.cs new file mode 100644 index 0000000..e5c1f81 --- /dev/null +++ b/GUI/SearchResultPageList.ascx.cs @@ -0,0 +1,124 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +namespace SD.HnD.GUI +{ + /// + /// Page list control for search results. + /// + public partial class SearchResultPageList : System.Web.UI.UserControl + { + + #region Class Member Declarations + private int _amountPages, _currentPage; + #endregion + + private void Page_Load(object sender, System.EventArgs e) + { + int[] pageNos = new int[_amountPages]; + + for(int i=0;i<_amountPages;i++) + { + pageNos[i]=(i+1); + } + + rptPageList.DataSource = pageNos; + rptPageList.DataBind(); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + this.rptPageList.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.rptPageList_ItemDataBound); + } + #endregion + + /// + /// Event handler for the ItemDataBound event for the repeater control. In here the decision is made + /// if the current item will be a link (we're not on this page) or not (thus a label) + /// + /// + /// + private void rptPageList_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + if(_currentPage == (int)e.Item.DataItem) + { + Label lblMessagePage = (Label)e.Item.FindControl("lblMessagesPage"); + lblMessagePage.Visible=true; + } + else + { + HyperLink lnkResultPage = (HyperLink)e.Item.FindControl("lnkResultPage"); + lnkResultPage.NavigateUrl += (int)e.Item.DataItem; + lnkResultPage.Visible=true; + } + break; + } + } + + #region Class Property Declarations + /// + /// sets amountPages + /// + public int AmountPages + { + set + { + _amountPages = value; + } + } + + /// + /// sets currentPage + /// + public int CurrentPage + { + set + { + _currentPage = value; + } + } + #endregion + } +} diff --git a/GUI/SearchResults.aspx b/GUI/SearchResults.aspx new file mode 100644 index 0000000..0bffa11 --- /dev/null +++ b/GUI/SearchResults.aspx @@ -0,0 +1,86 @@ +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Page language="c#" CodeFile="SearchResults.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.SearchResults" EnableViewState="false" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Import namespace="System.Data" %> +<%@ Register TagPrefix="HnD" TagName="SearchResultPageList" Src="SearchResultPageList.ascx"%> + + + + HnD::Search + + + + + +
    +

    +
    + + + + +
    + Search results for search on: + + The following words were skipped from your query, as they're ignored words: + + +
    + + + + + + + + + + + + + + + +
    + Number of threads found:
    +
    +
    + + + New search +
    + + + + + + + + + + + + + + + + + + + + + + + +
    ThreadForumLast post
    <%#Eval("SectionName") %> - <%#Eval("ForumName") %><%# ((DateTime)Eval("ThreadLastPostingDate")).ToString("dd-MMM-yyyy HH:mm")%>
    <%#Eval("SectionName") %> - <%#Eval("ForumName") %><%# ((DateTime)Eval("ThreadLastPostingDate")).ToString("dd-MMM-yyyy HH:mm")%>
    +
    + + + New search +
    +
    +
    + + + + diff --git a/GUI/SearchResults.aspx.cs b/GUI/SearchResults.aspx.cs new file mode 100644 index 0000000..8ae140b --- /dev/null +++ b/GUI/SearchResults.aspx.cs @@ -0,0 +1,141 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; + +using SD.HnD.BL; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// Code behind file for the SearchResults form + /// + public partial class SearchResults : System.Web.UI.Page + { + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int currentPage = HnDGeneralUtils.TryConvertToInt(Request["Page"]); + if(currentPage == 0) + { + currentPage = 1; + } + + if(!Page.IsPostBack) + { + plPageListTop.CurrentPage = currentPage; + plPageListBottom.CurrentPage = currentPage; + + DataTable results = SessionAdapter.GetSearchResults(); + if(results==null) + { + // no results, redirect to search page + Response.Redirect("Search.aspx"); + } + + short pageSize = CacheManager.GetSystemData().PageSizeSearchResults; + if(pageSize <= 0) + { + pageSize = 50; + } + + int amountPages = (results.Rows.Count/pageSize); + if((amountPages*pageSize) + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + rptResults.ItemDataBound +=new RepeaterItemEventHandler(rptResults_ItemDataBound); + } + #endregion + + /// + /// Event handler which will be called every time a row in the Repeater rpResults is bound to a row in the view. + /// + /// + /// + private void rptResults_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + HyperLink lnkThread = (HyperLink)e.Item.FindControl("lnkThread"); + string threadSubject = ((DataRowView)e.Item.DataItem)["Subject"].ToString(); + if(threadSubject.Length>50) + { + threadSubject=threadSubject.Substring(0, 50) + "..."; + } + lnkThread.Text = threadSubject; + break; + } + } + + } +} diff --git a/GUI/SearchUnAttended.aspx b/GUI/SearchUnAttended.aspx new file mode 100644 index 0000000..e78d6a9 --- /dev/null +++ b/GUI/SearchUnAttended.aspx @@ -0,0 +1 @@ +<%@ Page language="c#" CodeFile="SearchUnAttended.aspx.cs" AutoEventWireup="true" Inherits="SD.HnD.GUI.SearchUnAttended" %> \ No newline at end of file diff --git a/GUI/SearchUnAttended.aspx.cs b/GUI/SearchUnAttended.aspx.cs new file mode 100644 index 0000000..5cf5669 --- /dev/null +++ b/GUI/SearchUnAttended.aspx.cs @@ -0,0 +1,92 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Text; +using SD.HnD.BL; + +using SD.HnD.DAL.TypedListClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// the code here has to grab the querystring values, then setup the session and perform the search. It then + /// redirects to the search display page. + /// + public partial class SearchUnAttended : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // clear tmp results in session + SessionAdapter.AddSearchTermsAndResults(string.Empty, null); + // Read all accessable forums for the current user. + List accessableForums = SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum); + + string[] forumIDs = Request.QueryString.GetValues("ForumID"); + List forumIDsToSearchIn = new List(); + if(forumIDs!=null) + { + foreach(string forumIDAsString in forumIDs) + { + int forumID = HnDGeneralUtils.TryConvertToInt(forumIDAsString); + if(accessableForums.Contains(forumID)) + { + forumIDsToSearchIn.Add(forumID); + } + } + } + else + { + // add all forums the user has access to + forumIDsToSearchIn.AddRange(accessableForums); + } + + string searchTerms = Request.QueryString.Get("SearchTerms"); + if(searchTerms.Length > 1024) + { + searchTerms = searchTerms.Substring(0, 1024); + } + SearchResultTypedList results = BL.Searcher.DoSearch(searchTerms, forumIDsToSearchIn, SearchResultsOrderSetting.ForumAscending, + SearchResultsOrderSetting.LastPostDateDescending, SessionAdapter.GetForumsWithActionRight(ActionRights.ViewNormalThreadsStartedByOthers), + SessionAdapter.GetUserID(), SearchTarget.MessageText); + // store results in session. + SessionAdapter.AddSearchTermsAndResults(searchTerms, results); + // view results. + Response.Redirect("SearchResults.aspx?Page=1", true); + } + + + private void Page_PreInit(object sender, EventArgs e) + { + // switch off theming as the EnableTheming option on the page level doesn't work due to a bug in ASP.NET 2.0 + Page.Theme = ""; + } + } +} diff --git a/GUI/SupportQueues.aspx b/GUI/SupportQueues.aspx new file mode 100644 index 0000000..e52a029 --- /dev/null +++ b/GUI/SupportQueues.aspx @@ -0,0 +1,179 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SupportQueues.aspx.cs" Inherits="SD.HnD.GUI.SupportQueues" %> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageList" Src="PageList.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageLegend" Src="PageLegend.ascx"%> +<%@ Import Namespace="SD.HnD.GUI" %> +<%@ Import namespace="System.Web" %> +<%@ Import Namespace="System.Globalization" %> + + + + HnD::Support Queues + + + +
    + + + + + +
    +
    + You are here: Home > Support queues +

    +
    + + + + +
    +

    Support queues

    + Below you'll find the support queues defined in the forum system, ordered by their defined order no, ascending, as well as their containing threads. + Use the queues below to access threads which need attention. Be sure to claim a thread when you want to work on the thread and release the claim + of the thread when you're done. You can do that in this overview, however you can also do that in the message view of the thread. +

    + The list of threads in a queue is filtered by the forums you can access: threads located in forums you don't have access to aren't displayed. +
    +
    + + + + + + + + + + + + +
    + <%# Eval("QueueName") %> +
    + <%# Eval("QueueDescription") %> +
    + + + + + +
    + There are no threads in this queue. +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     Thread subjectLast postClaim
    + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +    
    +
    Posted in forum: <%# Eval("ForumName")%>.
    + Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    + Placed in queue by: <%# HttpUtility.HtmlEncode((string)Eval("NickNamePlacedInQueue"))%>
    + Placed in queue on: <%# ((DateTime)Eval("PlacedInQueueOn")).ToString("dd-MMM-yyyy HH:mm.ss", DateTimeFormatInfo.InvariantInfo) %> +
    +
    +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On: +

    + # replies: <%# ((int)Eval("AmountMessages")-1)%>
    + # views: <%# Eval("NumberOfViews")%> +
    +
    +
    + + by:
    + on: +
    + + + + +
    +
    + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +    
    +
    Posted in forum: <%# Eval("ForumName")%>.
    + Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    + Placed in queue by: <%# HttpUtility.HtmlEncode((string)Eval("NickNamePlacedInQueue"))%>
    + Placed in queue on: <%# ((DateTime)Eval("PlacedInQueueOn")).ToString("dd-MMM-yyyy HH:mm.ss", DateTimeFormatInfo.InvariantInfo) %> +
    +
    +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On: +

    + # replies: <%# ((int)Eval("AmountMessages")-1)%>
    + # views: <%# Eval("NumberOfViews")%> +
    +
    +
    + + by:
    + on: +
    + + + + +
    +
    + +
    +
    +
    + +

    +
    +
    +
    + +
    +
    + + + + diff --git a/GUI/SupportQueues.aspx.cs b/GUI/SupportQueues.aspx.cs new file mode 100644 index 0000000..323c6d0 --- /dev/null +++ b/GUI/SupportQueues.aspx.cs @@ -0,0 +1,205 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using SD.HnD.BL; +using SD.HnD.DAL.CollectionClasses; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; +using System.Globalization; + +namespace SD.HnD.GUI +{ + /// + /// Code behind for the SupportQueues page. + /// + public partial class SupportQueues : System.Web.UI.Page + { + protected void Page_Load(object sender, EventArgs e) + { + // check if the user has the right to be here + bool userMayManageQueues = SessionAdapter.HasSystemActionRight(ActionRights.QueueContentManagement); + if(!userMayManageQueues) + { + // doesn't have the right to manage queue contents. redirect + Response.Redirect("default.aspx", true); + } + + if(!Page.IsPostBack) + { + SupportQueueCollection supportQueues = CacheManager.GetAllSupportQueues(); + rpQueues.DataSource = supportQueues; + rpQueues.DataBind(); + } + } + + + /// + /// Handles the ItemDataBound event of the rptQueues control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void rpQueues_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + SupportQueueEntity currentSupportQueue = (SupportQueueEntity)e.Item.DataItem; + + // get the threads in the queue and bind it to the repeater. If there are no threads, show the placeholder and hide the repeater. + DataView threadsInQueue = SupportQueueGuiHelper.GetAllThreadsInSupportQueueAsDataView( + SessionAdapter.GetForumsWithActionRight(ActionRights.AccessForum), currentSupportQueue.QueueID); + + if(threadsInQueue.Count > 0) + { + // there is data, bind it to the repeater + + // Find repeater control in this item + Repeater rpThreads = (Repeater)e.Item.FindControl("rpThreads"); + + // bind it + rpThreads.DataSource = threadsInQueue; + rpThreads.DataBind(); + } + else + { + // no data, show the placeholder + PlaceHolder noDataText = (PlaceHolder)e.Item.FindControl("phNoDataText"); + noDataText.Visible = true; + } + break; + } + } + + + /// + /// Event handler which will be called every time a row in the Repeater rpThreads is bound to a row in the view. + /// + /// + /// + protected void rpThreads_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + // Thread has always a last posting date: a thread has at least 1 posting. + DateTime threadLastPostingDate = (DateTime)(((DataRowView)e.Item.DataItem)["ThreadLastPostingDate"]); + DateTime lastVisitDate = SessionAdapter.GetLastVisitDate(); + bool isSticky = (bool)(((DataRowView)e.Item.DataItem)["IsSticky"]); + bool isClosed = (bool)(((DataRowView)e.Item.DataItem)["IsClosed"]); + + // date is not 0, check if the date is > than the date in the session variable. If so, the posting is newer and we + // should visualize the New Messages image, otherwise the No new Messages image. Also take into account + // the type of the thread: sticky, closed or normal. + System.Web.UI.WebControls.Image imgIconPosts; + + if(threadLastPostingDate > lastVisitDate) + { + // there are new messages since last visit + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPosts"); + } + } + } + else + { + // no new messages + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPosts"); + } + } + } + imgIconPosts.Visible = true; + if(((DataRowView)e.Item.DataItem)["ClaimedByUserID"] != DBNull.Value) + { + // thread is claimed by someone + HyperLink lnkClaimerThread = (HyperLink)e.Item.FindControl("lnkClaimerThread"); + lnkClaimerThread.NavigateUrl += ((DataRowView)e.Item.DataItem)["ClaimedByUserID"].ToString(); + lnkClaimerThread.Text = HttpUtility.HtmlEncode((string)((DataRowView)e.Item.DataItem)["NickNameClaimedThread"]); + Label lblClaimDate = (Label)e.Item.FindControl("lblClaimDate"); + lblClaimDate.Text = ((DateTime)((DataRowView)e.Item.DataItem)["ClaimedOn"]).ToString("dd-MMM-yyyy HH:mm.ss", DateTimeFormatInfo.InvariantInfo); + } + break; + } + } + + + /// + /// Handles the ItemCommand event of the rpThreads control. + /// + /// The source of the event. + /// The instance containing the event data. + protected void rpThreads_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e) + { + switch(e.CommandName) + { + case "ReleaseClaim": + // release a claim on the thread. + SupportQueueManager.ReleaseClaimOnThread(HnDGeneralUtils.TryConvertToInt((string)e.CommandArgument)); + // done, refresh + Response.Redirect("SupportQueues.aspx", true); + break; + case "Claim": + // claim the thread specified for the current user + SupportQueueManager.ClaimThread(SessionAdapter.GetUserID(), HnDGeneralUtils.TryConvertToInt((string)e.CommandArgument)); + + // done, refresh + Response.Redirect("SupportQueues.aspx", true); + break; + } + } + } +} diff --git a/GUI/Threads.aspx b/GUI/Threads.aspx new file mode 100644 index 0000000..4734991 --- /dev/null +++ b/GUI/Threads.aspx @@ -0,0 +1,143 @@ +<%@ Page language="c#" CodeFile="Threads.aspx.cs" AutoEventWireup="false" Inherits="SD.HnD.GUI.Threads" %> +<%@ Import namespace="System.Web" %> +<%@ Import Namespace="System.Globalization" %> +<%@ Import Namespace="SD.HnD.GUI" %> +<%@ Register TagPrefix="HnD" TagName="PageFooter" Src="Footer.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageHeader" Src="Header.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageList" Src="PageList.ascx"%> +<%@ Register TagPrefix="HnD" TagName="PageLegend" Src="PageLegend.ascx"%> + + + + HnD::List all threads of forum: <%=base.ForumName%> + + + +
    + + +
    + + + + + + + + +
    +

    + You are here: Home > > +

    +
    + New Thread  +
    + + + + + + + + + + +
    +    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     Thread subjectRepliesViewsLast post
    + + + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +     +
    Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    +
    <%# ((int)Eval("AmountMessages"))-1%><%# Eval("NumberOfViews")%> +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On:
    +
    + + + + + + + + + + <%# HttpUtility.HtmlEncode((string)Eval("Subject"))%> +     +
    Started by: <%# HttpUtility.HtmlEncode((string)Eval("NickName"))%>
    +
    <%# ((int)Eval("AmountMessages"))-1%><%# Eval("NumberOfViews")%> +
    By: <%# HttpUtility.HtmlEncode((string)Eval("NickNameLastPosting"))%>
    + On:
    +
    + +
    + + + + + + +
      + New Thread + + Show threads of  + + ...last 24 hours + ...last 48 hours + ...last week + ...last month + ...last year + +
    + +
    +
    + + + + + diff --git a/GUI/Threads.aspx.cs b/GUI/Threads.aspx.cs new file mode 100644 index 0000000..b8907fe --- /dev/null +++ b/GUI/Threads.aspx.cs @@ -0,0 +1,228 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Web; +using System.Web.SessionState; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.HtmlControls; +using System.Globalization; +using System.Text; + +using SD.HnD.BL; +using SD.HnD.DAL.EntityClasses; +using SD.HnD.Utility; + +namespace SD.HnD.GUI +{ + /// + /// The code behind class for the Threads.aspx webform which enlists all threads in a given forum. + /// + public partial class Threads : System.Web.UI.Page + { + #region Class Member Declarations + private string _forumName; + #endregion + + /// + /// Handles the Load event of the Page control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Page_Load(object sender, System.EventArgs e) + { + int forumID=HnDGeneralUtils.TryConvertToInt(Request.QueryString["ForumID"]); + + bool userHasAccess = SessionAdapter.CanPerformForumActionRight(forumID, ActionRights.AccessForum); + if(!userHasAccess) + { + // doesn't have access to this forum. redirect + Response.Redirect("default.aspx"); + } + + bool userCanCreateThreads = (SessionAdapter.CanPerformForumActionRight(forumID, ActionRights.AddNormalThread) || + SessionAdapter.CanPerformForumActionRight(forumID, ActionRights.AddStickyThread)); + + // Controls are visible by default. Hide them when the user can't create threads on this forum + if(!userCanCreateThreads) + { + lnkNewThreadBottom.Visible=false; + lnkNewThreadTop.Visible=false; + } + + // fill the page's content + ForumEntity forum = CacheManager.GetForum(forumID); + if(forum==null) + { + // not found. + Response.Redirect("default.aspx"); + } + _forumName = forum.ForumName; + + if(!Page.IsPostBack) + { + cbxThreadListInterval.SelectedValue = forum.DefaultThreadListInterval.ToString(); + + string forumNameEncoded = HttpUtility.HtmlEncode(_forumName); + lblForumName.Text = forumNameEncoded; + lblForumName_Header.Text = HttpUtility.HtmlEncode(_forumName); + lblForumDescription.Text = HttpUtility.HtmlEncode(forum.ForumDescription); + lblSectionName.Text = CacheManager.GetSectionName(forum.SectionID); + + string newThreadURL = string.Format("{0}?ForumID={1}", lnkNewThreadTop.NavigateUrl, forumID); + lnkNewThreadTop.NavigateUrl = newThreadURL; + lnkNewThreadBottom.NavigateUrl = newThreadURL; + if(forum.HasRSSFeed) + { + lnkForumRSS.NavigateUrl += string.Format("?ForumID={0}", forumID); + } + else + { + lnkForumRSS.Visible=false; + litRssButtonSpacer.Visible=false; + } + } + + SystemDataEntity systemData = CacheManager.GetSystemData(); + int postLimiter = HnDGeneralUtils.TryConvertToInt(cbxThreadListInterval.SelectedValue); + DataView threadsView = ForumGuiHelper.GetAllThreadsInForumAsDataView(forumID, (ThreadListInterval)(byte)postLimiter, + systemData.MinNumberOfThreadsToFetch, systemData.MinNumberOfNonStickyVisibleThreads, + SessionAdapter.CanPerformForumActionRight(forumID, ActionRights.ViewNormalThreadsStartedByOthers), + SessionAdapter.GetUserID()); + + rpThreads.DataSource = threadsView; + rpThreads.DataBind(); + threadsView.Dispose(); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + // + // CODEGEN: This call is required by the ASP.NET Web Form Designer. + // + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.rpThreads.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.rpThreads_ItemDataBound); + this.cbxThreadListInterval.SelectedIndexChanged += new System.EventHandler(this.cbxThreadListInterval_SelectedIndexChanged); + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + + protected void cbxThreadListInterval_SelectedIndexChanged(object sender, System.EventArgs e) + { + // Empty routine, the postback will re-fill the threadlist. + } + + + /// + /// Event handler which will be called every time a row in the Repeater rpThreads is bound to a row in the view. + /// + /// + /// + private void rpThreads_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) + { + int maxAmountMessagesPerPage = SessionAdapter.GetUserDefaultNumberOfMessagesPerPage(); + + switch(e.Item.ItemType) + { + case ListItemType.AlternatingItem: + case ListItemType.Item: + // Thread has always a last posting date: a thread has at least 1 posting. + DateTime threadLastPostingDate = (DateTime)(((DataRowView)e.Item.DataItem)["ThreadLastPostingDate"]); + DateTime lastVisitDate = SessionAdapter.GetLastVisitDate(); + bool isSticky = (bool)(((DataRowView)e.Item.DataItem)["IsSticky"]); + bool isClosed = (bool)(((DataRowView)e.Item.DataItem)["IsClosed"]); + + // date is not 0, check if the date is > than the date in the session variable. If so, the posting is newer and we + // should visualize the New Messages image, otherwise the No new Messages image. Also take into account + // the type of the thread: sticky, closed or normal. + System.Web.UI.WebControls.Image imgIconPosts; + + if (threadLastPostingDate > lastVisitDate) + { + // there are new messages since last visit + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNewPosts"); + } + } + } + else + { + // no new messages + if(isSticky) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsSticky"); + } + else + { + if(isClosed) + { + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPostsClosed"); + } + else + { + // is normal + imgIconPosts = (System.Web.UI.WebControls.Image)e.Item.FindControl("imgIconNoNewPosts"); + } + } + } + imgIconPosts.Visible=true; + break; + } + } + + + #region Class Property Declarations + /// + /// Gets the name of the forum. + /// + /// The name of the forum. + protected string ForumName + { + get { return _forumName; } + } + #endregion + } +} diff --git a/GUI/Web.config b/GUI/Web.config new file mode 100644 index 0000000..833c3f3 --- /dev/null +++ b/GUI/Web.config @@ -0,0 +1,179 @@ + + + + + + + + +
    + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GUI/js/searchhi.js b/GUI/js/searchhi.js new file mode 100644 index 0000000..c5d95e7 --- /dev/null +++ b/GUI/js/searchhi.js @@ -0,0 +1,247 @@ +/* New: Variable searchhi_string to keep track of words being searched. */ +var searchhi_string = ''; + +/* http://www.kryogenix.org/code/browser/searchhi/ */ +/* Modified 20021006 to fix query string parsing and add case insensitivity */ +function highlightWord(node,word) { + // Iterate into this nodes childNodes + if (node.hasChildNodes) { + var hi_cn; + for (hi_cn=0;hi_cn 1 ) location.hash = location.hash; +} + + +function SmartHighlight() +{ + // This function is like SearchHighlight() + // but it detects a page refresh and toggles highlighting + // on each refresh. This gives a quick way to turn off + // highlighting (and quickly turn it on after). + + var today = new Date(); + var now = today.getUTCSeconds(); + + var cookie = document.cookie; + var cookieArray = cookie.split('; '); + + // Get timestamp stored in cookie + for (var loop=0; loop < cookieArray.length; loop++){ + var nameValue = cookieArray[loop].split("="); + if (nameValue[0].toString() == 'SHTS'){ + var cookieTime = parseInt( nameValue[1] ); + } + else if (nameValue[0].toString() == 'SHTSP'){ + var cookieName = nameValue[1]; + } + } + + // If we got a cookie, the cookie is from this page, + // and the cookie's time is very close to now, then + // this must be a page refresh (or very similar) + // so we don't want to highlight. (the 5 second threshold + // may need to be adjusted for slower browsers/pages/etc.) + if( cookieName && + cookieTime && + cookieName == escape(location.href) && + Math.abs(now - cookieTime) < 5 ) + { + // Refresh detected, so don't highlight + + // Disable refresh detection for this run; + // this is what allows us to toggle the highlighting + // back *ON* on the next refresh + searchhi_unl = 0; + } + else + { + // This is not a refresh, so highlight + SearchHighlight(); + } + +} + +function SmartHLUnload() +{ + if( searchhi_unl > 0 ) + { + // Turn refresh detection on so that if this + // page gets quickly loaded, we know it's a refresh + var today = new Date(); + var now = today.getUTCSeconds(); + document.cookie = 'SHTS=' + now + ';'; + document.cookie = 'SHTSP=' + escape(location.href) + ';'; + } + else + { + // Refresh detection has been disabled + document.cookie = 'SHTS=;'; + document.cookie = 'SHTSP=;'; + } +} + +function NotRefreshHL() +{ + // This is not a refresh. It's probably a submit + // with the same search string, so disable refresh + // detection on this go around. + searchhi_unl = 0; + return true; +} + +// By default, turn refresh detection on +var searchhi_unl = 1; + diff --git a/GUI/pics/attachment.gif b/GUI/pics/attachment.gif new file mode 100644 index 0000000000000000000000000000000000000000..fe01d355ae374e884615a50ab7611c35d13677b9 GIT binary patch literal 332 zcmZ?wbhEHb6krfwxN6B@>Y04u>TUm|YP-PfsN9y@_n$=Nw8R&71gF-;6||SN&kf6L zH1|$%2+4H}$=iG6Y*F*feMirpzIfBZJJr%R-6kNjsAZN*c!5WBNm5C-cU-xdSIU`7 zw=%0IUBCU{_}MG#wjKyctGDz?%dVZ0THd#L_fhw#V!NR1tGDjQaKqX^!`eSH zJgYIUVVYlJl~ZV5PVE%eh{F8F=@vd|KJgW$ZF5dtxcTz+yZ`_HGhhJ4pDc_F43-Q! zAQ_OK7}zoo%qj5Dkt#NCJ$lqqD0kJIlqWLh+E!|*Tt6vWv@lC&`pKp+0wq?(Wt@}=H zKX7`-!81D#p4oNi?5@LS_Z&I5=g9fJM=$I>cHzdIhqvxMzW?a?gU8RGJb(4{#hYg@ z-#&l!_T}q$uit)n^X}uj51+n%`~Ls`e}+*o8UnNr0boi~{K>+|!0?|z2V@&4PcU$F zGW_S1@z{{yD5~sK5%H0qfuWhnb;*zAP0okg1?+kD6kJs3sF(hi_``i+@ t>?yE-D{w)RxEj}v48;Yn_X~4G{An&^XuVml!^WZ!@M!JbMn*;kYXHO&wqyVR literal 0 HcmV?d00001 diff --git a/GUI/pics/separator.gif b/GUI/pics/separator.gif new file mode 100644 index 0000000000000000000000000000000000000000..106b95700ddb376de07654821a108b6606b75dd3 GIT binary patch literal 45 ucmZ?wbhEHbWMN=oXkcLY|NlP&1B2pE7Dgb&paUX6G7L;CE&ZIV4AubK*$3kQ literal 0 HcmV?d00001 diff --git a/GUI/pics/smileyangry.gif b/GUI/pics/smileyangry.gif new file mode 100644 index 0000000000000000000000000000000000000000..618f525ea249ae21509e139e2719ed309ed79fd0 GIT binary patch literal 315 zcmV-B0mS}CNk%w1VG#fk0K^{v`ts|~iD>qyg$f4+rD#mJcUk}H(9X1|;g@y)$eaJy zr&&8Gk5o97T|xidwz-9C=BkbI)yMs?jj3)=Zbvl#yOW(_M*qpE!F^t^aZ~M}eyM(E z-@~@WshTq)7XSbMA^8LW0018VEC2ui01*HY000HJ;3s|nU^vQkMZoBqN}N=Z07Wi| zE=n>>nni#!0-$083XL*A1PVlBtd|(nnodlnBuh*@p4!**Bpe*R8Q3GxtT6?`V@8uK zJPQrtzR(f~5;X#Y8hTCva2Xa25QT*Z6dnUf1qB%d78Vc)oB@(}p9B+&8yo?rcM}+J z4FevF3>^Ru7!4i;tCg1n3k(e{91{x@x)~Fg78DEzBL^0L(3uSku{j454GoLazRWo! N9UF@l8?r7T06SENb>sj5 literal 0 HcmV?d00001 diff --git a/GUI/pics/smileyconfused.gif b/GUI/pics/smileyconfused.gif new file mode 100644 index 0000000000000000000000000000000000000000..e91a21bdae9624076e0a40a239d45f8cfcffbd0c GIT binary patch literal 314 zcmV-A0mc4DNk%w1VG#fk0K^{v&b4RN%&uQkEd2M#=goWn|KXa4L;wG$|Mr}ScR&2$ zi}Trox}#bD?3Dfd^`eeS|Nge9l1s9rZnK?L?9+nW!*P>49@5l5Slj1LU8T} zLy3o|3QqzM7{Ly`A8kPqW{M7(4_G5qJd8=Fa7ZB@9#0MI0WdBBh_Vs(FxweMMAE3! z1Reo_fEQ#Y5f2K3HB5UI6##J;4+a#Ej|2$`iHcbf29Ah`0-Zx~2^tR;7#siq6$}Dq z8VL*!triv=9T~P7ei;|IxCXKv9|0E=6Im0CoxTZ0A{!48(1DH08#w{fnX(D9IU*e! M7`_G=v@Rh4JHC>8O8@`> literal 0 HcmV?d00001 diff --git a/GUI/pics/smileycool.gif b/GUI/pics/smileycool.gif new file mode 100644 index 0000000000000000000000000000000000000000..cbbcd929cf342764e86282cb4ecdb470cbb364e8 GIT binary patch literal 310 zcmV-60m=SHNk%w1VG#fk0K^{v`uXe8$f^DL&F|HN=FEDTheZGXs3jl~ZD2D0^`89U zjQ{JD)4FQ^{nJan`b{a9>u(x zKyWS@ z8)-t@jKBz>;q`t43d4hg89dOAblQPlOuPhi%k?}Wfrctkg$@SXuVleqK(++JwsVP0 z6nMzlMo?BT4i^&zdmR{Y6n+>M8W9DAi3J)AN(_Gx2M7}u85|W13>pUze~SkPgAN-2 z5*Qc{8XgCtvK9pv7A+hR7Y`5}2eKNr77jup0TU6+b`zV$8#&33kGKvN$2kBS8Mg%) It1ck`J3p&-?f?J) literal 0 HcmV?d00001 diff --git a/GUI/pics/smileydissapointed.gif b/GUI/pics/smileydissapointed.gif new file mode 100644 index 0000000000000000000000000000000000000000..887cd91785d587620a189b5418c173871c55ff3f GIT binary patch literal 309 zcmV-50m}YINk%w1VG#fk0K^{vT23nH&U^6Igwe>U{P)QJ|EKx*=9z{<|Ms5z;fw$5 zl)9r?g>*Wnl1rbANdEoz|Nge$#dFlVYqXwLvZQX#wr7)oKf|qIt(Q=#n`gnPUB$eb zJy|2Z1(rQ$QCC77QH+4nKo~6LV-?4i*_46%wKV01O9^6BrE# z78?c^8W*y#Ru~wQ78V8{92gV7zqSpCkwPK^4h_nDh^!17IRldi)VYwxIR+aUod+4N HE+GIr>3)A( literal 0 HcmV?d00001 diff --git a/GUI/pics/smileyembarrassed.gif b/GUI/pics/smileyembarrassed.gif new file mode 100644 index 0000000000000000000000000000000000000000..e019bd00f7fb5118457e2091b880dec6d248bc8e GIT binary patch literal 304 zcmV-00nh$NNk%w1VG#fk0K^{v|NpMDc24^F>Ep?F_VCBk%dEz2Rq@w>Sxzd)x|;v> zozqWFnubLG?3Ad7O#R}F*Sl@Wp@7Y`X5)!%x};dcgj=bSP1UAq#H?YfooS1CKbL?( zu$)$;k4-Zy7XSbMA^8LW0018VEC2ui01*HY000H8;3s~90Gx_K2xDuWfYLn2K(r(r z%k&@>qZf*Is7WZmm&TKtc{Brv1j8u-ma-Y`DWzBnF=j(s9C#oYZ)V)+AUZ{NM_Q?L z=9hl~`Apkol CD0t`q literal 0 HcmV?d00001 diff --git a/GUI/pics/smileylaugh.gif b/GUI/pics/smileylaugh.gif new file mode 100644 index 0000000000000000000000000000000000000000..ecaf6c8e2ffa5f616a4ec4566aff5dbe37bf126e GIT binary patch literal 309 zcmV-50m}YINk%w1VG#fk0K^{v{P)Q2)Pv2mX5q+pWLPl&|EKx+h@&Ep|y{21F+k`Wa^C=P=$5tRnI)`sNKTM#+~+nFG+G$so(1zGz6 z1rb66gCr0*fPsPp3!2ZjTa936~}9TW@|7a0Pd0v!k&qzDKMg%uhO z6A)Gq1f~cas0S4l1|Jy|7QMX`4GpOg5+f1}!NIk*5gIuX7?F{;5f#NbIuaMQ2NxQ- HBOw4gYma0 z%PMUHff39=>@8{&KqUB(88RNvu@O~L4u_&5Div^*4h^KoKzI-Wff)gyI4q1f=2#;T zCP_)fk)gBGc6a~<8x;)&X#!9acY+iN2o(j0j077V6iI^#9)=ef9RL7H9-Nm62@QuA z8V42;un`ET2^*>f7Z(Q~0TmPx6v2BAs}dR`8VwH1e5)4{9613Qlasj;tT`eF8W^|* J7_BZL06UT-cJ%-N literal 0 HcmV?d00001 diff --git a/GUI/pics/smileysad.gif b/GUI/pics/smileysad.gif new file mode 100644 index 0000000000000000000000000000000000000000..948ec3e0917cdae056f695f01dd95053da8afa40 GIT binary patch literal 310 zcmV-60m=SHNk%w1VG#fk0K^{v|NpJbwrU@cyxG>W`ughP$aU`2fcEgmnukRH_MTXL za=WEk|Lv8Ecsf!@DEi=vr;<&2Y&XC!lK^JjQ{`tA^8LW0018VEC2ui01*HY000HE;3s|r0h~#45MyheK*BtRceErN z%XAS8qZf+T3oL-boh0)JERC1aE|8H}4H1c>v4C`Ti2x^4Fc=DzYy`4kxCepK{{8oSZ$$t8wz#2Jy{Tl&%E*&}KitA_la76DUookhXTrOm zMLZzm+PpI?7XSbMA^8LW0018VEC2ui01*HY000HJ;3t02QAmiQ6wv4%5}H1XV07*W zOOB_~9>;|+f+2dpnjlEQL1aD!t!B7*CX>Sfkx~FWp4!(lm;eZp-vjKivC9C;V@_*$ z8U};CK`{dsfPexvRTl$r2?>LQ1^^ix92pi^0Eq$@m=_5R6#|Ms5y;EEO# z3jghuUQ#Xo{r9JmOaK13iFY`?rdy(oNZZ13w4PV3m{7T>Ym1OhWG7XSbMA^8LW0018VEC2ui01*HY000HG;3s~K@jL~B49)18Xu2cA|s^{ z2oofv;?UIFYIk`62OJd=2WkRO6L?5&3LOpyiFpJZ9u$uUksT5j836!~9ts|q7#JNL z2NxR+77l1tylbFG+Aw4PR?j!CklZo{l$shek&f~9+ zp^s6)s$MfJ7XSbMA^8LW0018VEC2ui01*HY000HI;3s|n;5f!{5Wwh~XsRTEK)B>- zq{kdcjKK)7+o@&=fdsM;nu^B+P03hLO2*!TF_lz2p2)_b>M0(Dv=SV)DBj4x<$|C< z9-c>pBb5d?H4;k<7Yh>)2my)$0S^m;5QJ6@8i|5}2p$ZPg%k({4;TZR5TzO(937Jd z9t|4+7aemK6dtT#X$=`I0}~X#6o+XA8V#-^8x;}D5fv2(85zee0~{F$(9yaZI3fTW M7|;k9uPz|~I}?q3DgXcg literal 0 HcmV?d00001 diff --git a/HnD.sln b/HnD.sln new file mode 100644 index 0000000..90c785c --- /dev/null +++ b/HnD.sln @@ -0,0 +1,85 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SD.HnD.BL", "BL\SD.HnD.BL.csproj", "{DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SD.HnD.DAL", "DAL\SD.HnD.DAL.csproj", "{43C8451A-A377-4589-BF7D-73BE386E7B4D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SD.HnD.Utility", "Utility\SD.HnD.Utility.csproj", "{AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}" +EndProject +Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "GUI", "GUI\", "{D1192B40-860F-4645-965E-688C1DEB1931}" + ProjectSection(WebsiteProperties) = preProject + TargetFrameworkMoniker = ".NETFramework,Version%3Dv3.5" + ProjectReferences = "{43C8451A-A377-4589-BF7D-73BE386E7B4D}|SD.HnD.DAL.dll;{AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}|SD.HnD.Utility.dll;{DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}|SD.HnD.BL.dll;" + Debug.AspNetCompiler.VirtualPath = "/GUI" + Debug.AspNetCompiler.PhysicalPath = "GUI\" + Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\GUI\" + Debug.AspNetCompiler.Updateable = "true" + Debug.AspNetCompiler.ForceOverwrite = "true" + Debug.AspNetCompiler.FixedNames = "false" + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.VirtualPath = "/GUI" + Release.AspNetCompiler.PhysicalPath = "GUI\" + Release.AspNetCompiler.TargetPath = "PrecompiledWeb\GUI\" + Release.AspNetCompiler.Updateable = "true" + Release.AspNetCompiler.ForceOverwrite = "true" + Release.AspNetCompiler.FixedNames = "false" + Release.AspNetCompiler.Debug = "False" + VWDPort = "3532" + DefaultWebSiteLanguage = "Visual C#" + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|.NET = Debug|.NET + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Release|.NET = Release|.NET + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Debug|.NET.ActiveCfg = Debug|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Release|.NET.ActiveCfg = Release|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Release|Any CPU.Build.0 = Release|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {DCF9E35B-D377-4B8C-A0BB-D31CD6A7EC1A}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Debug|.NET.ActiveCfg = Debug|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Release|.NET.ActiveCfg = Release|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Release|Any CPU.Build.0 = Release|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {43C8451A-A377-4589-BF7D-73BE386E7B4D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Debug|.NET.ActiveCfg = Debug|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Release|.NET.ActiveCfg = Release|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Release|Any CPU.Build.0 = Release|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Debug|.NET.ActiveCfg = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Release|.NET.ActiveCfg = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Release|Any CPU.ActiveCfg = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Release|Any CPU.Build.0 = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D1192B40-860F-4645-965E-688C1DEB1931}.Release|Mixed Platforms.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..6e812ec --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/LLBLGenPro Projects/HnD.lgp b/LLBLGenPro Projects/HnD.lgp new file mode 100644 index 0000000000000000000000000000000000000000..368162e8bdc76ae82cd5c74a14ebdaf7594c1b47 GIT binary patch literal 173561 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

    m5i^cgwCum!^stu)a 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 literal 0 HcmV?d00001 diff --git a/ParserAssemblies/SD.HnD.UBBParser.dll b/ParserAssemblies/SD.HnD.UBBParser.dll new file mode 100644 index 0000000000000000000000000000000000000000..e18f4a2c7aa04da00d3d495417e92980dbfb09c8 GIT binary patch literal 36864 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%0AxJm_ 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

    4){4PM95xn?7EY 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%0D9P3>ou} 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

    $a68y;NOZPH?DU*7L;2thV_H zuT*sVO)eGgO{d~Sr*^8IRCp^};;{ov4~tefmI0s(g*rwK#|wbi&;LF!#S*l?Cb&6l z=VKcJn%7r|*c$G+aPJQHE#cl1?ji#Di^YtxT6AC;DYoO++{rOf^8a~PE=4&GR)!J* z2A-_!B(Vw4BixAC-9{7Get%;5hn_auwa>jr-;&!8PIMwM-03s@x@cFU42P{{GTM(K zv)Pg?;{ogkj@AEqXkYd&xkc9bs=sfGR+aSjc5m9;lif<9Ry}*H^39!i3TY1rt#Z-4 z8nU)cwxDPuWH?8bRVK=h`NS}kNC=wLj)dmj236;@UK1LYryAZ}B2b0)TS%D>v*!(h zyi?_-Y^GP3TK=4KDh~P*8$;@B;xLCNCo58dgIRN@rZR)g-?Q{R{n;M*!|4y^Hk?Ve zPmDkD_&1(8_Q*4jJwEZw<0mGLJ$mf-k34kzXp&G$5C69^lJ)~*ZhgajIXD8~80NoX zHUn;MTOd+y;FB9uCU$%q=C`G5xVLM#r)!vsZ|xfH167-aHC;aC!fAEN2%O=ohx?ZA ze*DPoHAv0}CWxhj= zryT&_f@2Lfzonzi8YP%AUcXE4a5_M@COIDx;nN<4G!aq~-OuVykxbei;0~7q&C0`G z@afgorwS>vqGFOHgov@@(xla3mZc3!a%>o8HU9{?4Oz!Mz+ZyUSriUQ$f>f?zZLgc z_P4@wjT5@ETZqH6x6uzV|BcNB-;%T4OZ4j@w$T*w=`UN@<|S+mwgVvm|4qijupm1+ zmb0Rt9B*a+lYHa6Nm?&ah{k~)4jdg|d0G8=95PdmooHj~e`8*CutKWg0+#P0gCjA! z0K6p;OIbjVa*wOa6`2Es2#BKNsX&?oD^9f7cx4xzzwrvSGY58;G2{eZccKQn@)Tcr zdM7Pur5g|F##4#L@wt}pr$iD7Db%accx883hK#&G-R1WDS6mve7{J=17mFRYu}6#s zOWwE#s6Gjg%2JM_5(MhGM;OK%uOLc#p6Yr2Li>%q;v%2Y@$1Z@^GQRipn-1*6VZD1_RDGf-Y%7X7u zsa!@X)t(cVxp}-M2s)=pY3P`U-63BS@W}Z_e|%xrP$?NUE8( zlYZm!PN|}_R}O0?3>8*{)zN`3fIh(lM`|fQkQesGc3uHU(8o{!QnqPFFO2)T5d z#RBeP2a6Tvl9#hN?XKx`jU&AMMb^?7VZwaa>kj?Ghxi76 zsKbOb$NPaaWjdjdIvSVR*5WPOLeJTT3w*wLSS(Ndt9e*TV{tyEZyvTm@U8gfwqaXc z$KgVbsAj@@j`L}=x@KacuV$O#aXjL_USD-iCtMSCH#?s4k-A(0e^8o|rXco`#JuCG zl2?|j{43U(1~|~8i_NfpKg-TE)J{D*{Fo#%I=2>ffWGvfuPEZ0Up~(TS8?@us&!4( zO8lNH3|y=kM8Z0xV-$W|_c?mYv|#9JA{QTYSb=9PHTma|TZ+ zqkD*@qoRC6GX;4YG_Zk5P4b%C5dpLm;RyFFx|tn}Tzqt1;zDyN2nRoF zi3D-j_ zhgyphJA*=Jd}S?&58iq8VblaQ;gaI(qHk#gp!>^0rNzhOuiY0R)qIT#w|?Qf*KTwN zYB48e$te4w;pk1fe%BjR{{Rl43K(#_CbZuJr18L;Hbw1T`h)CF7jrP%^tUHjKF5+<$03M_ zs1b0WCm|$iTNyB17u=3@8Bb~3RMzwzq!6K5Koar(Y7D#{18=7(At-a2+-=S3Dxao< z0$zN!_QZz>*DGyGxT0?z+E<(st{5dKJ|@4|ri6?6X8RYuyLh9!Q-b9rO2Dq+l<>My z0$ZPXxwO^;t(eyrvpa49EeyRH}vDm@s1ZVj8=)?3DATlo@*V_X9pxUL2M<_+X57ih^@; z9F=Ipc4I;T_dY{sjQbL_#}kD3en>9nubC{{N5V>NOLLd&13*_^RR3vS&{=YlHSW}Z zGmqt)|KbqKtT{~(z2y6;9AnO{)H!9$e~EhH7o3b`dlCg}6D!eeQ*4w%+Kb|O_VVR~ zp-r%AhMyzM>X>(+7^)9(o(@CY^K8_>Yg3QViR=A+yzXT%VStociEYWHCPBVpp9Yj& zcS%i2Sj)?=nS#A#PB7N6-_Aa~n_b>SQpc1Cs7ttCNQbm<+?+>`BdeK6?{ z_deY<`@CkaKSd0$lY#UY)*NP^E{|(A#hTz=J7PWG^j))?O*8>J5*qbJOQv3#h%)uc zgmzvx!7VQX=0ScuO7LEp_(z#!_~Eaedh`OeTRUjr)HJ7I%+Jo8d9Hk6l>eN%o=LVI z7`<&kR*3xlDv7eaejv_N+6>$3(Ti8$=QdraDhWU=8N+e+dr~fsma0`t_qTVG*Wh)ZY(#88U;_dh5ZHjg1_U-BumOP$2>d;P z05UW!*^XawXM_AimwoHRE8RH%pMGy^a}<@ z`UqkDy}S8;{$Cx3yM@Dw{`IC@>;BvJmIHLTcZG1gjSoHDWPx)*Y}X~IczjW06E z!{j&3zcODhP)d?KL^(B{3zS$Pt;(NIF7Ui)@g+j1?RgRAcRcwWE3uHAAeUL*KMrOd zwR}}uwdS0a@La+qi@!0%|Jc?!Qp`~Q$3jZIKS}B;rAPRxUSs4^qsC`Qt-qI(1LP4g zh`zmm+gzEipz)p3*(k0ul3e1KZ*OTL_{_esj0WiU&?}H<8WT)7lfG14 zo}#AnR@X=yD&amW<&a(PPxkXKNzPMh#;8nqnx|z&N@_#mB&{A@(}K|e<X$MjorXTlzJf98$ySG#?7!Z zN}3~9Rw0$6a5!%`R7+nVRH9BvaxrG;+Ti&V?bU8_j+7xms$08`0&Vg#B5;q4SGr_)FC|%#FWS58C+KfWQU>HXyJ8fei?3Kwtv`8xZ&h z3xO+Jkv@~8aNj>z2y8Tb0|FZm*nq$W1U4YB0f7w&Y(QWG0viz6fWQU>HX!i#9s>Ul Dm@Yff literal 0 HcmV?d00001 diff --git a/SQLScripts/FullInstall_HnD.sql b/SQLScripts/FullInstall_HnD.sql new file mode 100644 index 0000000000000000000000000000000000000000..d2a4574f8c83163e2bddeccff7db9d01e0d082b3 GIT binary patch literal 91154 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 1 +exec sp_fulltext_database N'disable' +GO + +exec sp_fulltext_column N'[dbo].[Message]', N'MessageText', N'drop', 1033 +GO + +exec sp_fulltext_table N'[dbo].[Message]', N'drop' +GO + +exec sp_fulltext_column N'[dbo].[Thread]', N'Subject', N'drop', 1033 +GO + +exec sp_fulltext_table N'[dbo].[Thread]', N'drop' +GO + +-- alter columns using a generic script. credit: +-- http://forums.microsoft.com/technet/showpost.aspx?postid=1868356&siteid=17&sb=0&d=1&at=7&ft=11&tf=0&pageid=2 +DECLARE @rowCount int +DECLARE @altersql nvarchar(1024) +DECLARE @columnName nvarchar(256) +DECLARE @todatatable nvarchar(200) +DECLARE @size nvarchar(200) +DECLARE @aReturn nvarchar(256) +DECLARE @tableName nvarchar(256) +DECLARE @todatatype nvarchar(256) +DECLARE @patchName nvarchar(256) +DECLARE @nullable nvarchar(256) +DECLARE @existing nvarchar(256) +DECLARE @newcol nvarchar(256) + +BEGIN TRAN ConvertTypes + +SET @rowCount = 1 +SELECT +IDENTITY(int, 1, 1) AS aKey, +TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, +(CASE WHEN IS_NULLABLE='yes' THEN 'NULL' + WHEN IS_NULLABLE='no' AND DATA_TYPE='varchar' THEN 'NOT NULL' + WHEN IS_NULLABLE='no' AND DATA_TYPE='text' THEN 'NOT NULL CONSTRAINT [TEMP_DefaultValue] DEFAULT (N''test'')' END) AS nullable +INTO #TempColumns FROM INFORMATION_SCHEMA.COLUMNS +WHERE (DATA_TYPE='varchar' OR DATA_TYPE='text') AND TABLE_NAME NOT IN (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS) +AND TABLE_NAME != 'dtproperties' AND COLUMN_NAME NOT IN ('PostedFromIp', 'IPNumber') +ORDER BY TABLE_NAME + +WHILE @rowCount < (SELECT MAX(aKey) FROM #TempColumns) +BEGIN + SELECT @tablename=TABLE_NAME, @columnname=COLUMN_NAME, + @todatatype=(CASE WHEN DATA_TYPE='varchar' THEN 'nvarchar' WHEN DATA_TYPE='text' THEN 'ntext' END), + @size=(CASE WHEN DATA_TYPE='varchar' THEN '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS NVARCHAR(10)) + ') ' + WHEN DATA_TYPE='text' THEN ' ' END), + @nullable=nullable + FROM #TempColumns WHERE aKey=@rowCount + IF @todatatype='nvarchar' + BEGIN + SET @altersql = N'ALTER TABLE [dbo].[' + @tablename + '] ALTER COLUMN [' + @columnname + '] [' + @todatatype + '] ' + @size + @nullable + PRINT @altersql + EXEC @aReturn=[dbo].sp_executesql @altersql + IF @@ERROR <> 0 OR @aReturn <> 0 GOTO Error + END + ELSE + BEGIN + SELECT @existing = N'dbo.' + @tablename + '.' + @columnname, @newcol=@columnname + '_OLD' + PRINT N'-- [' + @patchName + '] - Rename existing column "' + @existing + '" to "' + @newcol + '".' + EXEC @aReturn=sp_rename @existing, @newcol, 'COLUMN' + IF @@ERROR <> 0 OR @aReturn <> 0 GOTO Error + + SET @altersql = N'ALTER TABLE [dbo].[' + @tablename + '] ADD [' + @columnname + '] [' + @todatatype + '] ' + @size + @nullable + PRINT N'-- [' + @patchName + '] - Add new NULLABLE column "' + @columnname + '".' + EXEC @aReturn=[dbo].sp_executesql @altersql + IF @@ERROR <> 0 OR @aReturn <> 0 + BEGIN + SET @existing = N'dbo.' + @tablename + '.' + @newcol + SET @newcol=@columnname + PRINT N' - ERROR, renaming changed column back.' + EXEC @aReturn=sp_rename @existing, @newcol, 'COLUMN' + IF @@ERROR <> 0 OR @aReturn <> 0 GOTO Error + + GOTO Error + END + + PRINT '-- [' + @patchName + '] - Update new column "' + @columnname + '" with data in column "' + @newcol + '".' + SET @altersql = N'UPDATE [dbo].[' + @tablename + '] SET [' + @columnname + ']=[' + @newcol + ']' + PRINT @altersql + EXEC @aReturn=[dbo].sp_executesql @altersql + IF @@ERROR <> 0 OR @aReturn <> 0 GOTO Error + + PRINT N'-- [' + @patchName + '] - Drop old column "' + @newcol + '".' + SET @altersql = N'ALTER TABLE [dbo].' + @tablename + ' DROP COLUMN [' + @newcol + ']' + EXEC @aReturn=[dbo].sp_executesql @altersql + IF @@ERROR <> 0 OR @aReturn <> 0 GOTO Error + + IF @todatatype='ntext' AND @nullable != 'NULL' + BEGIN + PRINT N'-- [' + @patchName + '] - Drop the temporary default constraint "TEMP_DefaultValue".' + SET @altersql = N'ALTER TABLE [dbo].[' + @tablename + '] DROP CONSTRAINT [TEMP_DefaultValue]' + EXEC @aReturn=[dbo].sp_executesql @altersql + IF @@ERROR <> 0 OR @aReturn <> 0 GOTO Error + END + END + + SET @rowCount = @rowCount + 1 +END + +COMMIT +GOTO Rebuild + +Error: +ROLLBACK +Return + +Rebuild: + +-- recreate indexes + CREATE UNIQUE INDEX [TF_ActionRight_AK1] ON [dbo].[ActionRight]([ActionRightDescription]) ON [PRIMARY] +GO + + CREATE UNIQUE INDEX [TF_Forum_AK1] ON [dbo].[Forum]([ForumName]) ON [PRIMARY] +GO + + CREATE UNIQUE INDEX [TF_Forum_AK2] ON [dbo].[Forum]([ForumDescription]) ON [PRIMARY] +GO + + CREATE UNIQUE INDEX [TF_Role_AK1] ON [dbo].[Role]([RoleDescription]) ON [PRIMARY] +GO + + CREATE UNIQUE INDEX [TF_Section_AK1] ON [dbo].[Section]([SectionName]) ON [PRIMARY] +GO + + CREATE UNIQUE INDEX [TF_Section_AK2] ON [dbo].[Section]([SectionDescription]) ON [PRIMARY] +GO + + CREATE INDEX [TF_Thread_AK1] ON [dbo].[Thread]([Subject]) ON [PRIMARY] +GO + + CREATE UNIQUE INDEX [TF_User_AK1] ON [dbo].[User]([NickName]) ON [PRIMARY] +GO + + CREATE UNIQUE INDEX [TF_UserTitle_AK1] ON [dbo].[UserTitle]([UserTitleDescription]) ON [PRIMARY] +GO + +ALTER TABLE [User] + ADD CONSTRAINT [TF_User_NickName_U2] UNIQUE NONCLUSTERED + ( + [NickName] + ) ON [PRIMARY] +GO + +-- Re-enable full text search +if (select DATABASEPROPERTY(DB_NAME(), N'IsFullTextEnabled')) <> 1 +exec sp_fulltext_database N'enable' +GO + +if not exists (select * from dbo.sysfulltextcatalogs where name = N'TF_FullTextCatalog') +exec sp_fulltext_catalog N'TF_FullTextCatalog', N'create' +GO + +exec sp_fulltext_table N'[dbo].[Message]', N'create', N'TF_FullTextCatalog', N'TF_Message_PK' +GO + +exec sp_fulltext_column N'[dbo].[Message]', N'MessageText', N'add', 1033 +GO + +exec sp_fulltext_table N'[dbo].[Message]', N'activate' +GO + +if (select DATABASEPROPERTY(DB_NAME(), N'IsFullTextEnabled')) <> 1 +exec sp_fulltext_database N'enable' +GO + +if not exists (select * from dbo.sysfulltextcatalogs where name = N'TF_FullTextCatalog') +exec sp_fulltext_catalog N'TF_FullTextCatalog', N'create' +GO + +exec sp_fulltext_table N'[dbo].[Thread]', N'create', N'TF_FullTextCatalog', N'TF_Thread_PK' +GO +exec sp_fulltext_column N'[dbo].[Thread]', N'Subject', N'add', 1033 +GO + +exec sp_fulltext_table N'[dbo].[Thread]', N'activate' +GO + + +--------------------------------------------------------------------------------------------- +-- Insert new AuditRight value +--------------------------------------------------------------------------------------------- +INSERT AuditAction (AuditActionID, AuditActionDescription) VALUES (6, N'Audit approve attachment') + +--------------------------------------------------------------------------------------------- +-- Drop of install proc and install of new one. +--------------------------------------------------------------------------------------------- + +if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[pr_Install]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) +drop procedure [dbo].[pr_Install] +GO + +SET QUOTED_IDENTIFIER ON +GO +SET ANSI_NULLS ON +GO + +----------------------- +-- Installs all necessary data to get the HnD system up and running. +CREATE PROCEDURE [pr_Install] + @sAdminEmailAddress nvarchar(150) +AS +DECLARE @iAnonymousRoleID int, + @iAdminRoleID int, + @iUserRoleID int, + @iUserID int, + @iUserTitleID int, + @iForumID int, + @iSectionID int + +-- CREATE ActionRights +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (1, N'Add and Edit Message', 1, 0) -- add a new message and edit your own +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (2, N'Access Forum', 1, 0) -- have access to a forum +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (3, N'User Management', 0, 1) -- set all kinds of userproperties/rights +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (4, N'Security Management', 0, 1) -- set rights on roles, create new roles, assign roles to forums etc. +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (5, N'Edit And Delete Other Users Messages', 1,0) -- edit other users' messages +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (6, N'Forum Specific Thread Management', 1, 0) -- edit thread's properties like sticky and closed, and move threads +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (7, N'System Management', 0, 1) -- change system settings like new section/forum etc. +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (8, N'Add and Edit Message in Sticky Thread', 1, 0) -- add a new message to a sticky thread and edit your own +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (9, N'System Wide Thread Management', 0, 1) -- administrate threads system wide. +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (10, N'Add Normal Thread', 1, 0) -- Add a normal thread to a forum +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (11, N'Add Sticky Thread', 1, 0) -- Add a sticky thread to a forum +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (12, N'Edit Thread Memo', 1, 0) -- Edit the memo field of a thread +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (13, N'Flag Thread As Done', 1, 0) -- Flag a thread not started by the user as done. +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (14, N'Queue Content Management', 0, 1) -- perform content management of support queues. +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (15, N'View Normal Threads Started by Others', 1, 0) -- view threads started by others in threadview and message view. +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (16, N'Manage Other Users Attachments', 1, 0) -- ability to manage/delete attachments of others +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (17, N'Add Attachment', 1, 0) -- Add an attachment to a message (and also delete it) +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (18, N'Gets Attachments Approved Automatically', 1, 0) -- Attachments added are approved automatically. +INSERT ActionRight (ActionRightID, ActionRightDescription, AppliesToForum, AppliesToSystem) + VALUES (19, N'Approve Attachment', 1, 0) -- Ability to approve and revoke approval of an attachment of a person. + +-- CREATE Administrators Role +INSERT Role (RoleDescription) + VALUES (N'Administrators Role') +SELECT @iAdminRoleID = SCOPE_IDENTITY() +-- CREATE UserTitle entry +INSERT UserTitle (UserTitleDescription) + VALUES (N'Administrator') +SELECT @iUserTitleID = SCOPE_IDENTITY() +-- CREATE Admin user +-- Password is MD5 hashed 'admin', or: ISMvKXpXpadDiUoOSoAfww== +INSERT [User] (NickName, Password, IsBanned, IPNumber, Signature, IconURL, EmailAddress, UserTitleID, DateOfBirth, Occupation, Location, Website, SignatureAsHTML, JoinDate, AmountOfPostings, EmailAddressIsPublic) + VALUES (N'Admin', N'ISMvKXpXpadDiUoOSoAfww==', 0, N'', N'', N'', @sAdminEmailAddress, @iUserTitleID, 0, N'', N'', N'', N'', GETDATE(), 0, 0) +SELECT @iUserID = SCOPE_IDENTITY() +-- Add new admin user to new role +INSERT RoleUser (RoleID, UserID) + VALUES (@iAdminRoleID, @iUserID) + +-- Add system rights to new role +INSERT RoleSystemActionRight (RoleID, ActionRightID) + VALUES (@iAdminRoleID, 3) +INSERT RoleSystemActionRight (RoleID, ActionRightID) + VALUES (@iAdminRoleID, 4) +INSERT RoleSystemActionRight (RoleID, ActionRightID) + VALUES (@iAdminRoleID, 7) +INSERT RoleSystemActionRight (RoleID, ActionRightID) + VALUES (@iAdminRoleID, 9) +INSERT RoleSystemActionRight (RoleID, ActionRightID) + VALUES (@iAdminRoleID, 14) + +-- CREATE Default User role +INSERT Role (RoleDescription) + VALUES (N'User Role') +SELECT @iUserRoleID = SCOPE_IDENTITY() +-- Add admin to this role +INSERT RoleUser (RoleID, UserID) + VALUES (@iUserRoleID, @iUserID) + +-- CREATE Anonymous Role +INSERT Role (RoleDescription) + VALUES (N'Anonymous user Role') +SELECT @iAnonymousRoleID = SCOPE_IDENTITY() + +-- CREATE UserTitle entry +INSERT UserTitle (UserTitleDescription) + VALUES (N'User') +SELECT @iUserTitleID = SCOPE_IDENTITY() + +-- CREATE Anonymous user. +SET IDENTITY_INSERT [User] ON +INSERT [User] (UserID, NickName, Password, IsBanned, IPNumber, Signature, IconURL, EmailAddress, + UserTitleID, DateOfBirth, Occupation, Location, Website, SignatureAsHTML, JoinDate, AmountOfPostings, EmailAddressIsPublic) + VALUES (0, N'Anonymous', N'', 0, N'', N'', N'', N'', @iUserTitleID, NULL, N'', N'', N'', N'', GETDATE(), 0, 0) +-- Add anonymous user to anonymous role +INSERT RoleUser (RoleID, UserID) + VALUES (@iAnonymousRoleID, 0) + +-- Insert the one row in the system data table. Set the values to the defaults. +INSERT SystemData(DefaultRoleNewUser, AnonymousRole, DefaultUserTitleNewUser, HoursThresholdForActiveThreads, PageSizeSearchResults, + MinNumberOfThreadsToFetch, MinNumberOfNonStickyVisibleThreads, SendReplyNotifications) + VALUES (@iUserRoleID, @iAnonymousRoleID, @iUserTitleID, 48, 25, 25, 5, 1) + +-- Create General Section +INSERT Section (SectionName, SectionDescription) + VALUES (N'General', N'Section with general forums') +SELECT @iSectionID = SCOPE_IDENTITY() + +-- Create General forum, place it in the general section +INSERT Forum (SectionID, ForumName, ForumDescription, ForumLastPostingDate) + VALUES (@iSectionID, N'General Chat', N'Forum for offtopic talk', NULL) +SELECT @iForumID = SCOPE_IDENTITY() + +-- Add all action rights which apply to forum for the admin role to the general chat forum +INSERT ForumRoleForumActionRight (ForumID, RoleID, ActionRightID) + SELECT @iForumID AS ForumID, + @iAdminRoleID, + ActionRightID + FROM ActionRight + WHERE AppliesToForum = 1 + +-- Add User role with the edit/add rights to this forum. +INSERT ForumRoleForumActionRight (ForumID, RoleID, ActionRightID) + VALUES(@iForumID, @iUserRoleID, 1) +-- Add User role with the access forum right to this forum. +INSERT ForumRoleForumActionRight (ForumID, RoleID, ActionRightID) + VALUES(@iForumID, @iUserRoleID, 2) +-- Add User role with the view other people's threads right to this forum +INSERT ForumRoleForumActionRight (ForumID, RoleID, ActionRightID) + VALUES(@iForumID, @iUserRoleID, 15) + +-- Add Anonymous role with the access forum right to this forum +INSERT ForumRoleForumActionRight (ForumID, RoleID, ActionRightID) + VALUES(@iForumID, @iAnonymousRoleID, 2) + +-- Add audit actions +INSERT AuditAction (AuditActionID, AuditActionDescription) VALUES (1, N'Audit login') +INSERT AuditAction (AuditActionID, AuditActionDescription) VALUES (2, N'Audit new message') +INSERT AuditAction (AuditActionID, AuditActionDescription) VALUES (3, N'Audit new thread') +INSERT AuditAction (AuditActionID, AuditActionDescription) VALUES (4, N'Audit altered message') +INSERT AuditAction (AuditActionID, AuditActionDescription) VALUES (5, N'Audit edit memo') +INSERT AuditAction (AuditActionID, AuditActionDescription) VALUES (6, N'Audit approve attachment') + +GO +SET QUOTED_IDENTIFIER OFF +GO +SET ANSI_NULLS ON +GO + + + + diff --git a/UBBParser/ParserTester/ExceptionViewer.cs b/UBBParser/ParserTester/ExceptionViewer.cs new file mode 100644 index 0000000..5a6a500 --- /dev/null +++ b/UBBParser/ParserTester/ExceptionViewer.cs @@ -0,0 +1,292 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; + +namespace ParserTester +{ + ///

    + /// Generic Exception viewer. + /// + internal class ExceptionViewer : System.Windows.Forms.Form + { + #region Class Member Declaration + private System.Windows.Forms.Label label1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Button _closeButton; + private Exception _exception; + private System.Windows.Forms.TextBox _sourceTextBox; + private System.Windows.Forms.RichTextBox _stackTraceTextBox; + private System.Windows.Forms.RichTextBox _messageTextBox; + private System.ComponentModel.Container components = null; + #endregion + + public ExceptionViewer() + { + InitializeComponent(); + } + + public ExceptionViewer(Exception exceptionToView) + { + InitializeComponent(); + _exception = exceptionToView; + ViewExceptionInWindow(); + } + + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + + /// + /// Purpose: will load the private membervariable m_kexException's data + /// into the windows' controls and thus view it. Set m_kexException with the + /// property kexException. + /// + public void ViewExceptionInWindow() + { + if(_exception==null) + { + // no exception loaded + _messageTextBox.Text = "No exception loaded into window: can't visualize exception"; + return; + } + // visualize the exception. + _stackTraceTextBox.SelectionBullet=true; + _messageTextBox.SelectionBullet=true; + _messageTextBox.Text += _exception.Message + Environment.NewLine; + _sourceTextBox.Text += _exception.Source + Environment.NewLine; + _stackTraceTextBox.Text += "-----[Core exception]--------------------" + Environment.NewLine; + _stackTraceTextBox.Text += _exception.StackTrace + Environment.NewLine; + // go into the inner exceptions. + for(Exception innerException = _exception.InnerException; + innerException!=null;innerException = innerException.InnerException) + { + _messageTextBox.Text += innerException.Message + Environment.NewLine; + _sourceTextBox.Text += innerException.Source + Environment.NewLine; + _stackTraceTextBox.Text += "-----[InnerException]--------------------" + Environment.NewLine; + _stackTraceTextBox.Text += innerException.StackTrace + Environment.NewLine; + } + // strip extra newline from boxes + _messageTextBox.Text = _messageTextBox.Text.Substring(0,_messageTextBox.Text.Length-1); + _sourceTextBox.Text = _sourceTextBox.Text.Substring(0,_sourceTextBox.Text.Length); + _stackTraceTextBox.Text = _stackTraceTextBox.Text.Substring(0,_stackTraceTextBox.Text.Length-1); + } + + #region Windows Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this._messageTextBox = new System.Windows.Forms.RichTextBox(); + this._stackTraceTextBox = new System.Windows.Forms.RichTextBox(); + this._sourceTextBox = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this._closeButton = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.BackColor = System.Drawing.Color.White; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(12, 6); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(503, 32); + this.label1.TabIndex = 0; + this.label1.Text = "An exception occured. Below is the general information about this exception. Clic" + + "k Close to close this window to resume."; + // + // groupBox1 + // + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Controls.Add(this._messageTextBox); + this.groupBox1.Controls.Add(this._stackTraceTextBox); + this.groupBox1.Controls.Add(this._sourceTextBox); + this.groupBox1.Controls.Add(this.label6); + this.groupBox1.Controls.Add(this.label5); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Location = new System.Drawing.Point(4, 54); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(525, 451); + this.groupBox1.TabIndex = 1; + this.groupBox1.TabStop = false; + this.groupBox1.Text = ".NET Exception information"; + // + // _messageTextBox + // + this._messageTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._messageTextBox.BulletIndent = 10; + this._messageTextBox.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this._messageTextBox.Location = new System.Drawing.Point(8, 36); + this._messageTextBox.Name = "_messageTextBox"; + this._messageTextBox.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical; + this._messageTextBox.Size = new System.Drawing.Size(511, 88); + this._messageTextBox.TabIndex = 2; + this._messageTextBox.Text = ""; + // + // _stackTraceTextBox + // + this._stackTraceTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._stackTraceTextBox.BackColor = System.Drawing.SystemColors.Window; + this._stackTraceTextBox.BulletIndent = 10; + this._stackTraceTextBox.CausesValidation = false; + this._stackTraceTextBox.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this._stackTraceTextBox.Location = new System.Drawing.Point(8, 148); + this._stackTraceTextBox.Name = "_stackTraceTextBox"; + this._stackTraceTextBox.ReadOnly = true; + this._stackTraceTextBox.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical; + this._stackTraceTextBox.Size = new System.Drawing.Size(511, 218); + this._stackTraceTextBox.TabIndex = 3; + this._stackTraceTextBox.Text = ""; + // + // _sourceTextBox + // + this._sourceTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._sourceTextBox.BackColor = System.Drawing.SystemColors.Window; + this._sourceTextBox.Location = new System.Drawing.Point(8, 390); + this._sourceTextBox.Multiline = true; + this._sourceTextBox.Name = "_sourceTextBox"; + this._sourceTextBox.ReadOnly = true; + this._sourceTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this._sourceTextBox.Size = new System.Drawing.Size(509, 52); + this._sourceTextBox.TabIndex = 4; + // + // label6 + // + this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label6.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label6.Location = new System.Drawing.Point(8, 374); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(60, 16); + this.label6.TabIndex = 4; + this.label6.Text = "Source"; + // + // label5 + // + this.label5.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label5.Location = new System.Drawing.Point(8, 132); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(188, 16); + this.label5.TabIndex = 2; + this.label5.Text = "Stack trace"; + // + // label4 + // + this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label4.Location = new System.Drawing.Point(8, 20); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(64, 16); + this.label4.TabIndex = 0; + this.label4.Text = "Message"; + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label3.BackColor = System.Drawing.Color.White; + this.label3.Location = new System.Drawing.Point(0, 0); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(535, 48); + this.label3.TabIndex = 3; + // + // _closeButton + // + this._closeButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this._closeButton.Location = new System.Drawing.Point(239, 511); + this._closeButton.Name = "_closeButton"; + this._closeButton.Size = new System.Drawing.Size(48, 24); + this._closeButton.TabIndex = 5; + this._closeButton.Text = "Close"; + this._closeButton.Click += new System.EventHandler(this._closeButton_Click); + // + // ExceptionViewer + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(535, 541); + this.Controls.Add(this._closeButton); + this.Controls.Add(this.label1); + this.Controls.Add(this.label3); + this.Controls.Add(this.groupBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ExceptionViewer"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Exception Viewer"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + #endregion + + private void _closeButton_Click(object sender, System.EventArgs e) + { + this.Close(); + } + + /// + /// Purpose: sets the membervariable _exception which is visualized + /// in the windows controls using ViewExceptionInWindow() + /// + public Exception ExceptionToView + { + set + { + _exception = value; + } + } + } +} diff --git a/UBBParser/ParserTester/ExceptionViewer.resx b/UBBParser/ParserTester/ExceptionViewer.resx new file mode 100644 index 0000000..ff31a6d --- /dev/null +++ b/UBBParser/ParserTester/ExceptionViewer.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UBBParser/ParserTester/LICENSE.txt b/UBBParser/ParserTester/LICENSE.txt new file mode 100644 index 0000000..6e812ec --- /dev/null +++ b/UBBParser/ParserTester/LICENSE.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/UBBParser/ParserTester/MainForm.Designer.cs b/UBBParser/ParserTester/MainForm.Designer.cs new file mode 100644 index 0000000..451be3d --- /dev/null +++ b/UBBParser/ParserTester/MainForm.Designer.cs @@ -0,0 +1,255 @@ +namespace ParserTester +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if(disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this._textToParseTextBox = new System.Windows.Forms.TextBox(); + this._startParseButton = new System.Windows.Forms.Button(); + this.label4 = new System.Windows.Forms.Label(); + this._inputFilenameTextBox = new System.Windows.Forms.TextBox(); + this._loadInputButton = new System.Windows.Forms.Button(); + this._mainTabControl = new System.Windows.Forms.TabControl(); + this._inputoutputTab = new System.Windows.Forms.TabPage(); + this._parseLogTab = new System.Windows.Forms.TabPage(); + this._parseTreeTreeView = new System.Windows.Forms.TreeView(); + this.label5 = new System.Windows.Forms.Label(); + this._logTextBox = new System.Windows.Forms.TextBox(); + this._destinationFileTextBox = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this._mainTabControl.SuspendLayout(); + this._inputoutputTab.SuspendLayout(); + this._parseLogTab.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(6, 34); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(69, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Text to parse"; + // + // _textToParseTextBox + // + this._textToParseTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._textToParseTextBox.Location = new System.Drawing.Point(81, 34); + this._textToParseTextBox.MaxLength = 99999999; + this._textToParseTextBox.Multiline = true; + this._textToParseTextBox.Name = "_textToParseTextBox"; + this._textToParseTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this._textToParseTextBox.Size = new System.Drawing.Size(584, 362); + this._textToParseTextBox.TabIndex = 1; + // + // _startParseButton + // + this._startParseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this._startParseButton.Location = new System.Drawing.Point(81, 402); + this._startParseButton.Name = "_startParseButton"; + this._startParseButton.Size = new System.Drawing.Size(125, 23); + this._startParseButton.TabIndex = 2; + this._startParseButton.Text = "Start parse"; + this._startParseButton.UseVisualStyleBackColor = true; + this._startParseButton.Click += new System.EventHandler(this._startParseButton_Click); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(6, 11); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(72, 13); + this.label4.TabIndex = 0; + this.label4.Text = "UBB Input file"; + // + // _inputFilenameTextBox + // + this._inputFilenameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._inputFilenameTextBox.Location = new System.Drawing.Point(81, 8); + this._inputFilenameTextBox.Name = "_inputFilenameTextBox"; + this._inputFilenameTextBox.Size = new System.Drawing.Size(503, 20); + this._inputFilenameTextBox.TabIndex = 3; + // + // _loadInputButton + // + this._loadInputButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this._loadInputButton.Location = new System.Drawing.Point(590, 6); + this._loadInputButton.Name = "_loadInputButton"; + this._loadInputButton.Size = new System.Drawing.Size(75, 23); + this._loadInputButton.TabIndex = 5; + this._loadInputButton.Text = "Load"; + this._loadInputButton.UseVisualStyleBackColor = true; + this._loadInputButton.Click += new System.EventHandler(this._loadInputButton_Click); + // + // _mainTabControl + // + this._mainTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._mainTabControl.Controls.Add(this._inputoutputTab); + this._mainTabControl.Controls.Add(this._parseLogTab); + this._mainTabControl.Location = new System.Drawing.Point(6, 6); + this._mainTabControl.Name = "_mainTabControl"; + this._mainTabControl.SelectedIndex = 0; + this._mainTabControl.Size = new System.Drawing.Size(679, 582); + this._mainTabControl.TabIndex = 6; + // + // _inputoutputTab + // + this._inputoutputTab.Controls.Add(this._logTextBox); + this._inputoutputTab.Controls.Add(this._destinationFileTextBox); + this._inputoutputTab.Controls.Add(this.label2); + this._inputoutputTab.Controls.Add(this.label3); + this._inputoutputTab.Controls.Add(this._textToParseTextBox); + this._inputoutputTab.Controls.Add(this._loadInputButton); + this._inputoutputTab.Controls.Add(this.label1); + this._inputoutputTab.Controls.Add(this.label4); + this._inputoutputTab.Controls.Add(this._inputFilenameTextBox); + this._inputoutputTab.Controls.Add(this._startParseButton); + this._inputoutputTab.Location = new System.Drawing.Point(4, 22); + this._inputoutputTab.Name = "_inputoutputTab"; + this._inputoutputTab.Padding = new System.Windows.Forms.Padding(3); + this._inputoutputTab.Size = new System.Drawing.Size(671, 556); + this._inputoutputTab.TabIndex = 0; + this._inputoutputTab.Text = "Input / Output"; + this._inputoutputTab.UseVisualStyleBackColor = true; + // + // _parseLogTab + // + this._parseLogTab.Controls.Add(this.label5); + this._parseLogTab.Controls.Add(this._parseTreeTreeView); + this._parseLogTab.Location = new System.Drawing.Point(4, 22); + this._parseLogTab.Name = "_parseLogTab"; + this._parseLogTab.Padding = new System.Windows.Forms.Padding(3); + this._parseLogTab.Size = new System.Drawing.Size(671, 556); + this._parseLogTab.TabIndex = 1; + this._parseLogTab.Text = "Parser output info"; + this._parseLogTab.UseVisualStyleBackColor = true; + // + // _parseTreeTreeView + // + this._parseTreeTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._parseTreeTreeView.Location = new System.Drawing.Point(5, 19); + this._parseTreeTreeView.Name = "_parseTreeTreeView"; + this._parseTreeTreeView.Size = new System.Drawing.Size(662, 531); + this._parseTreeTreeView.TabIndex = 0; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(2, 3); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(55, 13); + this.label5.TabIndex = 1; + this.label5.Text = "Parse tree"; + // + // _logTextBox + // + this._logTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._logTextBox.Location = new System.Drawing.Point(81, 442); + this._logTextBox.MaxLength = 999999999; + this._logTextBox.Multiline = true; + this._logTextBox.Name = "_logTextBox"; + this._logTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this._logTextBox.Size = new System.Drawing.Size(584, 82); + this._logTextBox.TabIndex = 9; + // + // _destinationFileTextBox + // + this._destinationFileTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._destinationFileTextBox.Location = new System.Drawing.Point(111, 530); + this._destinationFileTextBox.Name = "_destinationFileTextBox"; + this._destinationFileTextBox.Size = new System.Drawing.Size(554, 20); + this._destinationFileTextBox.TabIndex = 8; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(6, 533); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(99, 13); + this.label2.TabIndex = 6; + this.label2.Text = "XML destination file"; + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(19, 445); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(56, 13); + this.label3.TabIndex = 7; + this.label3.Text = "Output log"; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(689, 592); + this.Controls.Add(this._mainTabControl); + this.Name = "MainForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "UBB to Xml parser tester"; + this._mainTabControl.ResumeLayout(false); + this._inputoutputTab.ResumeLayout(false); + this._inputoutputTab.PerformLayout(); + this._parseLogTab.ResumeLayout(false); + this._parseLogTab.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox _textToParseTextBox; + private System.Windows.Forms.Button _startParseButton; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox _inputFilenameTextBox; + private System.Windows.Forms.Button _loadInputButton; + private System.Windows.Forms.TabControl _mainTabControl; + private System.Windows.Forms.TabPage _inputoutputTab; + private System.Windows.Forms.TabPage _parseLogTab; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TreeView _parseTreeTreeView; + private System.Windows.Forms.TextBox _logTextBox; + private System.Windows.Forms.TextBox _destinationFileTextBox; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + } +} + diff --git a/UBBParser/ParserTester/MainForm.cs b/UBBParser/ParserTester/MainForm.cs new file mode 100644 index 0000000..081fa3a --- /dev/null +++ b/UBBParser/ParserTester/MainForm.cs @@ -0,0 +1,139 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using SD.HnD.UBBParser; +using System.Xml; +using System.IO; + +namespace ParserTester +{ + public partial class MainForm : Form + { + public MainForm() + { + InitializeComponent(); + _destinationFileTextBox.Text = "output.xml"; + _inputFilenameTextBox.Text = "input.txt"; + } + + private void _startParseButton_Click(object sender, EventArgs e) + { + if(_textToParseTextBox.Text.Length <= 0) + { + return; + } + + _logTextBox.Text = string.Empty; + LogLine("Parsing started."); + + Parser textParser = new Parser(_textToParseTextBox.Text); + List parseTree = textParser.StartParseProcess(); + Interpreter tokenInterpreter = new Interpreter(parseTree); + XmlDocument result = tokenInterpreter.Interpret(); + + LogLine("Parsing ended."); + + string outputfilename = Path.Combine(Environment.CurrentDirectory, _destinationFileTextBox.Text); + StreamWriter writer = new StreamWriter(outputfilename, false); + writer.Write(result.OuterXml); + writer.Close(); + + LogLine("Output written as XML to " + outputfilename); + + ViewParseTree(parseTree); + } + + + /// + /// Views the parse tree in the treeview. + /// + /// The parse tree. + private void ViewParseTree(List parseTree) + { + _parseTreeTreeView.BeginUpdate(); + _parseTreeTreeView.Nodes.Clear(); + + TreeNode rootNode = _parseTreeTreeView.Nodes.Add("Parse tree"); + rootNode.ForeColor = Color.Blue; + foreach(NonTerminal currentNT in parseTree) + { + TreeNode ntNode = rootNode.Nodes.Add(currentNT.Type.ToString()); + ntNode.ForeColor = Color.Brown; + TreeNode tokensNode = ntNode.Nodes.Add("Tokens"); + tokensNode.ForeColor = Color.Blue; + foreach(IToken token in currentNT.Tokens) + { + TreeNode tokenNode = tokensNode.Nodes.Add(((Token)token.TokenID).ToString()); + tokenNode.ForeColor = Color.DarkMagenta; + tokenNode.Nodes.Add(String.Format(">{0}<", BeautifyText(token.LiteralMatchedTokenText))); + } + } + rootNode.ExpandAll(); + _parseTreeTreeView.EndUpdate(); + } + + /// + /// Beautifies the text passed in. Converts raw \r\t\n chars to visible text + /// + /// To beautify. + /// + private string BeautifyText(string toBeautify) + { + return toBeautify.Replace("\r", @"\r").Replace("\n", @"\n").Replace("\t", @"\t"); + } + + + private void LogLine(string toLog) + { + _logTextBox.Text += toLog + Environment.NewLine; + } + + + private void _loadInputButton_Click(object sender, EventArgs e) + { + string filename = Path.Combine(Environment.CurrentDirectory, _inputFilenameTextBox.Text); + if(!File.Exists(filename)) + { + LogLine("File {0} doesn't exist", filename); + return; + } + StreamReader reader = new StreamReader(filename); + _textToParseTextBox.Text = reader.ReadToEnd(); + reader.Close(); + } + + + /// + /// Logs the line. + /// + /// The formatted string. + /// The operands. + private void LogLine(string formattedString, params object[] operands) + { + LogLine(String.Format(formattedString, operands)); + } + } +} \ No newline at end of file diff --git a/UBBParser/ParserTester/MainForm.resx b/UBBParser/ParserTester/MainForm.resx new file mode 100644 index 0000000..ff31a6d --- /dev/null +++ b/UBBParser/ParserTester/MainForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UBBParser/ParserTester/Program.cs b/UBBParser/ParserTester/Program.cs new file mode 100644 index 0000000..b6965cb --- /dev/null +++ b/UBBParser/ParserTester/Program.cs @@ -0,0 +1,46 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace ParserTester +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); + Application.Run(new MainForm()); + } + + static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) + { + ExceptionViewer viewer = new ExceptionViewer(e.Exception); + viewer.ShowDialog(); + } + } +} \ No newline at end of file diff --git a/UBBParser/ParserTester/Properties/AssemblyInfo.cs b/UBBParser/ParserTester/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..20f6a16 --- /dev/null +++ b/UBBParser/ParserTester/Properties/AssemblyInfo.cs @@ -0,0 +1,52 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ParserTester")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ParserTester")] +[assembly: AssemblyCopyright("Copyright © 2006")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2e2f8656-9dd3-4b15-ab59-a04525d46500")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UBBParser/ParserTester/Properties/Resources.Designer.cs b/UBBParser/ParserTester/Properties/Resources.Designer.cs new file mode 100644 index 0000000..0d75458 --- /dev/null +++ b/UBBParser/ParserTester/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.166 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ParserTester.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ParserTester.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/UBBParser/ParserTester/Properties/Resources.resx b/UBBParser/ParserTester/Properties/Resources.resx new file mode 100644 index 0000000..ffecec8 --- /dev/null +++ b/UBBParser/ParserTester/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UBBParser/ParserTester/Properties/Settings.Designer.cs b/UBBParser/ParserTester/Properties/Settings.Designer.cs new file mode 100644 index 0000000..0dd9438 --- /dev/null +++ b/UBBParser/ParserTester/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.166 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ParserTester.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/UBBParser/ParserTester/Properties/Settings.settings b/UBBParser/ParserTester/Properties/Settings.settings new file mode 100644 index 0000000..abf36c5 --- /dev/null +++ b/UBBParser/ParserTester/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/UBBParser/ParserTester/Tester.csproj b/UBBParser/ParserTester/Tester.csproj new file mode 100644 index 0000000..d7afd67 --- /dev/null +++ b/UBBParser/ParserTester/Tester.csproj @@ -0,0 +1,94 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {D32F2A6C-D650-40BC-9A74-24190B3D970A} + WinExe + Properties + ParserTester + ParserTester + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + Form + + + Form + + + MainForm.cs + + + + + ExceptionViewer.cs + Designer + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {22A260C0-742F-42A7-82AB-DDB792082900} + UBBParser + + + + + + + + \ No newline at end of file diff --git a/UBBParser/UBBParser/AssemblyInfo.cs b/UBBParser/UBBParser/AssemblyInfo.cs new file mode 100644 index 0000000..80c83e2 --- /dev/null +++ b/UBBParser/UBBParser/AssemblyInfo.cs @@ -0,0 +1,77 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("HnD.UBBParser")] +[assembly: AssemblyDescription("HnD's UBB Parser")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Solutions Design")] +[assembly: AssemblyProduct("HnD, a .NET 2.0 Forum system using LLBLGen Pro")] +[assembly: AssemblyCopyright("(c)2002-2006 Solutions Design")] +[assembly: AssemblyTrademark("HnD, LLBLGen and LLBLGen Pro are trademarks of Solutions Design.")] +[assembly: AssemblyCulture("")] + + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("2.0.0.0")] +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/UBBParser/UBBParser/Converter.cs b/UBBParser/UBBParser/Converter.cs new file mode 100644 index 0000000..a5fc6ac --- /dev/null +++ b/UBBParser/UBBParser/Converter.cs @@ -0,0 +1,46 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace SD.HnD.UBBParser +{ + /// + /// Entry point for the complete UBB Parser. Use this class to convert a string in UBB syntaxis to XML. + /// + public static class Converter + { + /// + /// Converts the passed in string with UBB tokens to XML. + /// + /// The string to convert. + /// An XmlDocument object with the string with UBB tokens in Xml format. This XmlDocument is now usable to convert the string to + /// for example HTML by using a Xslt stylesheet. + public static XmlDocument ConvertToXml(string toConvert) + { + Parser textParser = new Parser(toConvert); + List parseTree = textParser.StartParseProcess(); + Interpreter tokenInterpreter = new Interpreter(parseTree); + return tokenInterpreter.Interpret(); + } + } +} diff --git a/UBBParser/UBBParser/EnumsConstants.cs b/UBBParser/UBBParser/EnumsConstants.cs new file mode 100644 index 0000000..1c88553 --- /dev/null +++ b/UBBParser/UBBParser/EnumsConstants.cs @@ -0,0 +1,159 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; + +namespace SD.HnD.UBBParser +{ + /// + /// General Enumeration of build in tokens, which are tokens which should always have these IDs + /// + public enum BuildInTokenID:int + { + /// + /// TokenID for the marking of EOF or '$', which means the end of the tokenstream. No special actions required. + /// + EOF=0, + /// + /// TokenID for the literal unquoted string, i.e. the literal text which doesn't match with any token definition. + /// All parsers using this Lexical analyzer should support this token. It contains all scanned characters which + /// didn't lead to a match with the passed in set of tokendefinitions. + /// + UntokenizedLiteralString + } + + + /// + /// Tokendefinitions for this parser + /// + public enum Token:int + { + EOF=0, // Mandatory First TokenID + UntokenizedLiteralString, // , Mandatory Second TokenID + AltTerminal, // 'alt' + Assignment, // '=' + BoldTextStartTag, // '[b]' + BoldTextEndTag, // '[/b]' + CodeTextStartTag, // '[code' + CodeTextEndTag, // '[/code]' + ColoredTextStartTag, // '[color' + ColoredTextEndTag, // '[/color]' + CR, // \r + DescriptionTerminal, // 'description' + EmailAddress, // any legitimate emailaddress representation + ImageStartTag, // '[img' + ImageEndTag, // '[/img]' + ImageURL, // URI starting with http:// and ending with .png, .jpg, .gif + ItalicTextStartTag, // '[i]' + ItalicTextEndTag, // '[/i]' + ListEndTag, // '[/list]' + ListItemEndTag, // '[/*]' + ListItemStartTag, // '[*]' + ListStartTag, // '[list' + LF, // \n + NickTerminal, // 'nick' + OfftopicTextStartTag, // '[offtopic]' + OfftopicTextEndTag, // '[/offtopic]' + QuotedString, // "text" + QuotedTextStartTag, // '[quote' + QuotedTextEndTag, // '[/quote]' + SizedTextStartTag, // '[size' + SizedTextEndTag, // '[/size]' + SingleQuotedNumericString, // ''0', '1', ..., '9'' + SmileyLaugh, // ':D' + SmileyAngry, // ':(' + SmileyRegular, // ':)' + SmileyWink, // ';)' + SmileyCool, // '8)' + SmileyTongue, // ':P' + SmileyConfused, // ':?' + SmileyShocked, // ':o' + SmileyDissapointed, // ':/' + SmileySad, // ';(' + SmileyEmbarrassed, // ':!' + StrikedTextStartTag, // '[s]' + StrikedTextEndTag, // '[/s]' + Tab, // ' ' or '\t' + TagCloseBracket, // ']' + TypeTerminal, // 'type' + UnderlinedTextStartTag, // '[u]' + UnderlinedTextEndTag, // '[/u]' + URLStartTag, // '[url ' + URLEndTag, // '[/url]' + URI, // URL starting with http://, https:// or www + ValueTerminal, // 'value' + WhiteSpace // ' ' + // insert more smiley tokens here + } + + + /// + /// Non-terminal type definitions. These values are used to specify the nonterminal type of a + /// NonTerminal object. The interpreter can then handle the nonterminal objects according + /// to their nonterminal Type. + /// + public enum NonTerminalType:int + { + BoldTextStart, + BoldTextEnd, + CodeTextStart, + CodeTextEnd, + ColoredTextStart, + ColoredTextEnd, + CRLF, + EmailAddress, + ImageStart, + ImageEnd, + ImageURL, + ItalicTextStart, + ItalicTextEnd, + ListStart, + ListItemStart, + ListItemEnd, + ListEnd, + LiteralText, + OfftopicTextStart, + OfftopicTextEnd, + QuotedTextStart, + QuotedTextEnd, + SizedTextStart, + SizedTextEnd, + SmileyLaugh, + SmileyAngry, + SmileyRegular, + SmileyWink, + SmileyCool, + SmileyTongue, + SmileyConfused, + SmileyShocked, + SmileyDissapointed, + SmileySad, + SmileyEmbarrassed, + StrikedTextStart, + StrikedTextEnd, + Tab, + UnderlinedTextStart, + UnderlinedTextEnd, + URLStart, + URLEnd, + URI, + // add more here + AmountOfNonTerminalTypes + } +} diff --git a/UBBParser/UBBParser/Exceptions.cs b/UBBParser/UBBParser/Exceptions.cs new file mode 100644 index 0000000..5bcb478 --- /dev/null +++ b/UBBParser/UBBParser/Exceptions.cs @@ -0,0 +1,37 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; + +namespace SD.HnD.UBBParser +{ + /// + /// Exception which is thrown when the Tokenize process is started without any Token definitions present + /// + public class NoTokenDefinitionsSpecifiedException : ApplicationException + { + /// + /// Creates a new instance. + /// + /// S message. + public NoTokenDefinitionsSpecifiedException(string sMessage): base(sMessage) + { + } + } +} \ No newline at end of file diff --git a/UBBParser/UBBParser/Interfaces.cs b/UBBParser/UBBParser/Interfaces.cs new file mode 100644 index 0000000..60779fb --- /dev/null +++ b/UBBParser/UBBParser/Interfaces.cs @@ -0,0 +1,75 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System.Collections; +using System.Text.RegularExpressions; + +namespace SD.HnD.UBBParser +{ + #region Interface definitions + /// + /// Interface for the TokenDefinition class. + /// + public interface ITokenDefinition + { + /// + /// // Token factory, which will create a tokenobject from this definition. Should fill in TokenID and RelatedTokenDefinition + /// + /// Token definition + IToken CreateTokenFromDefinition(); + + /// + /// Gets or sets the token ID. + /// + /// + int TokenID {get; set;} + /// + /// Gets or sets the matching regular expression. + /// + /// + Regex MatchingRegularExpression {get; set;} + } + + /// + /// Interface for the Token class. + /// + public interface IToken + { + /// + /// // masquerading property to retrieve data from RelatedTokenDefinition + /// + int TokenID {get; } + /// + /// Gets or sets the literal matched token text. + /// + /// + string LiteralMatchedTokenText {get; set;} + /// + /// Gets or sets the related token definition. + /// + /// + ITokenDefinition RelatedTokenDefinition {get; set;} + /// + /// Gets or sets the start index in input stream. + /// + /// + int StartIndexInInputStream {get; set;} + } + #endregion +} \ No newline at end of file diff --git a/UBBParser/UBBParser/Interpreter.cs b/UBBParser/UBBParser/Interpreter.cs new file mode 100644 index 0000000..7bbf5fa --- /dev/null +++ b/UBBParser/UBBParser/Interpreter.cs @@ -0,0 +1,810 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.IO; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; +using System.ComponentModel; +using System.Reflection; +using System.Collections.Generic; +using System.Xml; + +namespace SD.HnD.UBBParser +{ + /// + /// Generic UBB interpreter which interprets non-terminals, produced by the UBB parser and produces XML + /// + public class Interpreter + { + #region Class Member Declarations + private MemoryStream _outputStream; + private List _parseTree; + private int _nonTerminalIndex; + private XmlWriter _outputWriter; + #endregion + + + /// + /// Ctor. Sets up the interpreter + /// + /// List with non-terminals to interpret + public Interpreter(List parseTree) + { + _parseTree = parseTree; + _nonTerminalIndex = 0; + _outputStream = new MemoryStream(8192); // reserve 8KB + + XmlWriterSettings outputSettings = new XmlWriterSettings(); + outputSettings.OmitXmlDeclaration=true; + _outputWriter = XmlWriter.Create(_outputStream, outputSettings); + } + + + /// + /// Walks the complete parse tree, and each non-terminal found is handled by its handler. The + /// handler will check out the member parameters of this class if it can do something. + /// + /// + public XmlDocument Interpret() + { + // write rootnode, which has to be generaltext. + _outputWriter.WriteStartElement("generaltext"); + + while(_nonTerminalIndex < _parseTree.Count) + { + // main loop which handles top level general text elements. + GeneralTextNTHandler(); + _nonTerminalIndex++; + } + + // write end node of rootnode. + _outputWriter.WriteEndElement(); + _outputWriter.Close(); + + // done, convert the stream as an XmlDocument + _outputStream.Seek(0, SeekOrigin.Begin); // seek to start so load can read from the beginning. + XmlDocument toReturn = new XmlDocument(); + toReturn.Load(_outputStream); + _outputStream.Close(); + return toReturn; + } + + + /// + /// Handles all nonterminals from the current position. This routine will + /// return when the passed in nonterminal is seen. The passed in nonterminal is the current nonterminal after this routine ends. + /// + /// The nonterminal type which marks the end of the tokenstream to walk. + private void InnerGeneralTextHandler(NonTerminalType endType) + { + while((_nonTerminalIndex < _parseTree.Count)&&(_parseTree[_nonTerminalIndex].Type != endType)) + { + GeneralTextNTHandler(); + _nonTerminalIndex++; + } + } + + + /// + /// Handles all nonterminals from the current position. This routine will + /// return when the passed in nonterminal is seen. The passed in nonterminal is the current nonterminal after this routine ends. + /// + /// The nonterminal type which marks the end of the tokenstream to walk. + /// If set to true, CrLf tokens are handled, otherwise skipped as normal text + /// Routine used to handle the nonterminals inside code text and other nonterminals which only allow literal text inside themselves. + /// This is done in a separate loop because not all nonterminals can be located inside code text for example, see syntaxis + private void InnerLiteralTextHandler(NonTerminalType endType, bool allowCrLf) + { + while((_nonTerminalIndex < _parseTree.Count) && (_parseTree[_nonTerminalIndex].Type != endType)) + { + if(allowCrLf) + { + switch(_parseTree[_nonTerminalIndex].Type) + { + case NonTerminalType.CRLF: + HandleCrLf(); + break; + case NonTerminalType.Tab: + HandleTab(); + break; + default: + HandleLiteralText(false); + break; + } + } + else + { + switch(_parseTree[_nonTerminalIndex].Type) + { + case NonTerminalType.Tab: + HandleTab(); + break; + default: + HandleLiteralText(false); + break; + } + } + _nonTerminalIndex++; + } + } + + + /// + /// Handles all nonterminals from the current position. This routine will + /// return when the passed in nonterminal is seen. The passed in nonterminal is the current nonterminal after this routine ends. + /// + /// The nonterminal type which marks the end of the tokenstream to walk. + /// Routine used to handle the nonterminals inside formatted text. This is done in a separate loop because not all nonterminals can + /// be located inside formatted text, see syntaxis + private void InnerFormattedTextHandler(NonTerminalType endType) + { + while((_nonTerminalIndex < _parseTree.Count) && (_parseTree[_nonTerminalIndex].Type != endType)) + { + FormattedTextNTHandler(); + _nonTerminalIndex++; + } + } + + + /// + /// Handles all nonterminals inside a List nonterminal. It expects listitemstart/end pairs. + /// + private void InnerListHandler() + { + while((_nonTerminalIndex < _parseTree.Count) && (_parseTree[_nonTerminalIndex].Type != NonTerminalType.ListEnd)) + { + switch(_parseTree[_nonTerminalIndex].Type) + { + case NonTerminalType.ListItemStart: + HandleListItemStart(); + break; + default: + // not-allowed nonterminal, like literal text. Ignore this nonterminal, so it's filtered out. + break; + } + _nonTerminalIndex++; + } + } + + + /// + /// Handles all nonterminals from the current position for formatted text inside nonterminals which can only handle formatted text. This routine will + /// return when an end element is seen of a nonterminal which can be part of FormattedText. See syntax. + /// + private void FormattedTextNTHandler() + { + switch(_parseTree[_nonTerminalIndex].Type) + { + case NonTerminalType.BoldTextStart: + HandleSimpleFormattedTextStart(); + break; + case NonTerminalType.ColoredTextStart: + HandleColoredTextStart(); + break; + case NonTerminalType.CRLF: + HandleCrLf(); + break; + case NonTerminalType.EmailAddress: + HandleEmailAddress(); + break; + case NonTerminalType.ItalicTextStart: + HandleSimpleFormattedTextStart(); + break; + case NonTerminalType.LiteralText: + HandleLiteralText(); + break; + case NonTerminalType.OfftopicTextStart: + HandleOfftopicTextStart(); + break; + case NonTerminalType.SizedTextStart: + HandleSizedTextStart(); + break; + case NonTerminalType.SmileyAngry: + case NonTerminalType.SmileyConfused: + case NonTerminalType.SmileyCool: + case NonTerminalType.SmileyDissapointed: + case NonTerminalType.SmileyEmbarrassed: + case NonTerminalType.SmileyLaugh: + case NonTerminalType.SmileyRegular: + case NonTerminalType.SmileySad: + case NonTerminalType.SmileyShocked: + case NonTerminalType.SmileyTongue: + case NonTerminalType.SmileyWink: + HandleSmiley(); + break; + case NonTerminalType.StrikedTextStart: + HandleSimpleFormattedTextStart(); + break; + case NonTerminalType.Tab: + HandleTab(); + break; + case NonTerminalType.UnderlinedTextStart: + HandleSimpleFormattedTextStart(); + break; + case NonTerminalType.URI: + HandleUri(); + break; + default: + // error in this scope. This means that a tag is placed inside another tag where it's not allowed. + // the token is now pushed as normal literal text + HandleLiteralText(); + break; + } + } + + + /// + /// Looks at the non-terminal at position _nonTerminalIndex of the parse result array list and calls the handler. + /// + private void GeneralTextNTHandler() + { + switch(_parseTree[_nonTerminalIndex].Type) + { + case NonTerminalType.BoldTextStart: + HandleSimpleFormattedTextStart(); + break; + case NonTerminalType.CodeTextStart: + HandleCodeTextStart(); + break; + case NonTerminalType.ColoredTextStart: + HandleColoredTextStart(); + break; + case NonTerminalType.CRLF: + HandleCrLf(); + break; + case NonTerminalType.EmailAddress: + HandleEmailAddress(); + break; + case NonTerminalType.ImageStart: + HandleImageStart(); + break; + case NonTerminalType.ItalicTextStart: + HandleSimpleFormattedTextStart(); + break; + case NonTerminalType.ListStart: + HandleListStart(); + break; + case NonTerminalType.LiteralText: + HandleLiteralText(); + break; + case NonTerminalType.OfftopicTextStart: + HandleOfftopicTextStart(); + break; + case NonTerminalType.QuotedTextStart: + HandleQuotedTextStart(); + break; + case NonTerminalType.SizedTextStart: + HandleSizedTextStart(); + break; + case NonTerminalType.SmileyAngry: + case NonTerminalType.SmileyConfused: + case NonTerminalType.SmileyCool: + case NonTerminalType.SmileyDissapointed: + case NonTerminalType.SmileyEmbarrassed: + case NonTerminalType.SmileyLaugh: + case NonTerminalType.SmileyRegular: + case NonTerminalType.SmileySad: + case NonTerminalType.SmileyShocked: + case NonTerminalType.SmileyTongue: + case NonTerminalType.SmileyWink: + HandleSmiley(); + break; + case NonTerminalType.StrikedTextStart: + HandleSimpleFormattedTextStart(); + break; + case NonTerminalType.Tab: + HandleTab(); + break; + case NonTerminalType.UnderlinedTextStart: + HandleSimpleFormattedTextStart(); + break; + case NonTerminalType.URI: + HandleUri(); + break; + case NonTerminalType.URLStart: + HandleUrlStart(); + break; + default: + // no handler found/needed. Skip + break; + } + } + + + /// + /// Handles a CRLF nonterminal. + /// + private void HandleCrLf() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + _outputWriter.WriteStartElement("br"); + // done + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles the tab nonterminal + /// + private void HandleTab() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + _outputWriter.WriteStartElement("tab"); + // done + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles quoted text start. + /// + private void HandleQuotedTextStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + // current contains the tokens. A quoted text start nonterminal always contains one of the following token sets + // 0 1 2 3 4 + // [quote nick = string ] + // + // or: + // + // 0 1 2 + // [quote ] + + bool nickSpecified = current.Tokens.Count == 5; + string nick = string.Empty; + if(nickSpecified) + { + nick = StripFromQuotes(current.Tokens[3].LiteralMatchedTokenText); + } + + _outputWriter.WriteStartElement("quote"); + if(nickSpecified) + { + _outputWriter.WriteAttributeString("nick", nick); + } + + _nonTerminalIndex++; + InnerGeneralTextHandler(NonTerminalType.QuotedTextEnd); + + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles url start. This handler handles the complete [url...]URI[/url] sequence. + /// + private void HandleUrlStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + string url = string.Empty; + // current contains the tokens. An url start nonterminal always contains one of the following token sets + // 0 1 2 3 4 5 6 + // [url description = string ] URI [/url] + // + // or: + // + // 0 1 2 3 + // [url ] URI [/url] + + bool descriptionSpecified = current.Tokens.Count == 7; + string descriptionText = string.Empty; + if(descriptionSpecified) + { + descriptionText = StripFromQuotes(current.Tokens[3].LiteralMatchedTokenText); + url = current.Tokens[5].LiteralMatchedTokenText; + } + else + { + url = current.Tokens[2].LiteralMatchedTokenText; + } + + _outputWriter.WriteStartElement("url"); + if(descriptionSpecified) + { + _outputWriter.WriteAttributeString("description", descriptionText); + } + _outputWriter.WriteString(url); + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles image start. This handler handles the complete [img...]ImageUrl[/img] sequence. + /// + private void HandleImageStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + string imageSrc = string.Empty; + // current contains the tokens. An image start nonterminal always contains one of the following token sets + // 0 1 2 3 4 5 6 + // [img alt = string ] ImageURL [/img] + // + // or: + // + // 0 1 2 3 + // [img ] ImageURL [/img] + + bool altSpecified = current.Tokens.Count == 7; + string altText = string.Empty; + if(altSpecified) + { + altText = StripFromQuotes(current.Tokens[3].LiteralMatchedTokenText); + imageSrc = current.Tokens[5].LiteralMatchedTokenText; + } + else + { + imageSrc = current.Tokens[2].LiteralMatchedTokenText; + } + + _outputWriter.WriteStartElement("image"); + if(altSpecified) + { + _outputWriter.WriteAttributeString("alt", altText); + } + _outputWriter.WriteString(imageSrc); + _outputWriter.WriteEndElement(); + } + + + + /// + /// Handles List start. + /// + private void HandleListStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + // current contains the tokens. A list start nonterminal always contains one of the following token sets + // 0 1 2 3 4 + // [list type = string ] + // + // or: + // + // 0 1 + // [img ] + + bool typeSpecified = current.Tokens.Count == 5; + string listType = string.Empty; + if(typeSpecified) + { + string listTypeAsString = StripFromQuotes(current.Tokens[3].LiteralMatchedTokenText).ToUpperInvariant(); + switch(listTypeAsString) + { + case "UL": + case "OL": + listType = listTypeAsString; + break; + default: + listType = "UL"; + break; + } + } + + _outputWriter.WriteStartElement("list"); + if(typeSpecified) + { + _outputWriter.WriteAttributeString("type", listType); + } + _outputWriter.WriteStartElement("listitems"); + + _nonTerminalIndex++; + + // handle list items. + InnerListHandler(); + + _outputWriter.WriteEndElement(); // listitems + _outputWriter.WriteEndElement(); // list + } + + + /// + /// Handles colored text start. colored text contains a token which has to be a 6character long hex string. If the value is off, black is used. + /// + private void HandleColoredTextStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + string defaultColor = "000000"; + NonTerminalType endType = NonTerminalType.ColoredTextEnd; + // current contains the tokens. A color start nonterminal always contains the following tokens + // 0 1 2 3 + // [color value = string ] + + string colorValueAsString = StripFromQuotes(current.Tokens[3].LiteralMatchedTokenText); + if(colorValueAsString.Length != 6) + { + colorValueAsString = defaultColor; + } + + _outputWriter.WriteStartElement("color"); + _outputWriter.WriteAttributeString("value", colorValueAsString); + + _nonTerminalIndex++; + + // as the text inside a formatted text block has limited scope, we have to call a special handler. + InnerFormattedTextHandler(endType); + + // done + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles the EmailAddress nonterminal. + /// + private void HandleEmailAddress() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + // current contains the tokens. An emailaddress nonterminal always contains just one token, the actual emailaddress + string emailaddress = current.Tokens[0].LiteralMatchedTokenText; + _outputWriter.WriteElementString("emailaddress", emailaddress); + } + + + /// + /// Handles the literal text nonterminal. + /// + private void HandleLiteralText() + { + HandleLiteralText(true); + } + + + /// + /// Handles the literal text nonterminal. + /// + /// if set to true, it will emit the surrounding element literaltext as well. + private void HandleLiteralText(bool emitSurroundingElement) + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + if(emitSurroundingElement) + { + _outputWriter.WriteStartElement("literaltext"); + } + foreach(IToken token in current.Tokens) + { + // simply dump the token's literal text as literal text into the output + string text = token.LiteralMatchedTokenText; + _outputWriter.WriteElementString("literaltextelement", text); + } + if(emitSurroundingElement) + { + _outputWriter.WriteEndElement(); + } + } + + + /// + /// Handles code text start. + /// + private void HandleCodeTextStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + NonTerminalType endType = NonTerminalType.CodeTextEnd; + _outputWriter.WriteStartElement("code"); + + _nonTerminalIndex++; + + // as the text inside a formatted text block has limited scope, we have to call a special handler. + InnerLiteralTextHandler(endType, true); + + // done + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles offtopic text start. + /// + private void HandleOfftopicTextStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + _outputWriter.WriteStartElement("offtopic"); + + _nonTerminalIndex++; + + // as the text inside a formatted text block has limited scope, we have to call a special handler. + InnerFormattedTextHandler(NonTerminalType.OfftopicTextEnd); + + // done + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles listitem start. + /// + private void HandleListItemStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + _outputWriter.WriteStartElement("listitem"); + + _nonTerminalIndex++; + + InnerGeneralTextHandler(NonTerminalType.ListItemEnd); + + // done + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles sized text start. Sized text contains a token which has to be a 1 character long string. If the value is wrong, 3 (default) is used + /// + private void HandleSizedTextStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + string defaultSize = "3"; + NonTerminalType endType = NonTerminalType.SizedTextEnd; + // current contains the tokens. A sized text start nonterminal always contains the following tokens + // 0 1 2 3 + // [size value = string ] + + string sizedValueAsString = StripFromQuotes(current.Tokens[3].LiteralMatchedTokenText); + if((sizedValueAsString.Length != 1) && !Char.IsDigit(sizedValueAsString, 0)) + { + sizedValueAsString = defaultSize; + } + + _outputWriter.WriteStartElement("size"); + _outputWriter.WriteAttributeString("value", sizedValueAsString); + + _nonTerminalIndex++; + + // as the text inside a formatted text block has limited scope, we have to call a special handler. + InnerFormattedTextHandler(endType); + + // done + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles a smiley nonterminal. + /// + private void HandleSmiley() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + string tag = "smileyregular"; + switch((Token)current.Tokens[0].TokenID) + { + case Token.SmileyAngry: + tag = "smileyangry"; + break; + case Token.SmileyConfused: + tag = "smileyconfused"; + break; + case Token.SmileyCool: + tag = "smileycool"; + break; + case Token.SmileyDissapointed: + tag = "smileydissapointed"; + break; + case Token.SmileyEmbarrassed: + tag = "smileyembarrassed"; + break; + case Token.SmileyLaugh: + tag = "smileylaugh"; + break; + case Token.SmileyRegular: + tag = "smileyregular"; + break; + case Token.SmileySad: + tag = "smileysad"; + break; + case Token.SmileyShocked: + tag = "smileyshocked"; + break; + case Token.SmileyTongue: + tag = "smileytongue"; + break; + case Token.SmileyWink: + tag = "smileywink"; + break; + } + + _outputWriter.WriteStartElement(tag); + _outputWriter.WriteEndElement(); + } + + + /// + /// Handles the URI nonterminal. + /// + private void HandleUri() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + // current contains the tokens. An URI nonterminal always contains just one token, the actual URI + string uri = current.Tokens[0].LiteralMatchedTokenText; + _outputWriter.WriteElementString("url", uri); + } + + + /// + /// Handles simply formatted text start. Simple formatted text is text surrounded with bold,italic, striked or underlined. + /// + private void HandleSimpleFormattedTextStart() + { + NonTerminal current = _parseTree[_nonTerminalIndex]; + + string tag = string.Empty; + NonTerminalType endType = NonTerminalType.BoldTextEnd; + switch(current.Type) + { + case NonTerminalType.BoldTextStart: + tag = "bold"; + endType = NonTerminalType.BoldTextEnd; + break; + case NonTerminalType.ItalicTextStart: + tag = "italic"; + endType = NonTerminalType.ItalicTextEnd; + break; + case NonTerminalType.StrikedTextStart: + tag = "striked"; + endType = NonTerminalType.StrikedTextEnd; + break; + case NonTerminalType.UnderlinedTextStart: + tag = "underlined"; + endType = NonTerminalType.UnderlinedTextEnd; + break; + default: + // error + return; + } + + _outputWriter.WriteStartElement(tag); + + _nonTerminalIndex++; + + // as the text inside a formatted text block has limited scope, we have to call a special handler. + InnerFormattedTextHandler(endType); + + // done + _outputWriter.WriteEndElement(); + } + + + /// + /// Strips the passed in string from quotes (double or single) + /// + /// To strip. + /// toStrip without the surrounding quotes. + private string StripFromQuotes(string toStrip) + { + if(toStrip.Length < 3) + { + return string.Empty; + } + return toStrip.Substring(1, toStrip.Length - 2); + } + + } +} diff --git a/UBBParser/UBBParser/LICENSE.txt b/UBBParser/UBBParser/LICENSE.txt new file mode 100644 index 0000000..6e812ec --- /dev/null +++ b/UBBParser/UBBParser/LICENSE.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/UBBParser/UBBParser/LexicalAnalyzer.cs b/UBBParser/UBBParser/LexicalAnalyzer.cs new file mode 100644 index 0000000..e985600 --- /dev/null +++ b/UBBParser/UBBParser/LexicalAnalyzer.cs @@ -0,0 +1,76 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace SD.HnD.UBBParser +{ + /// + /// Lexical Analyzer class. A parser creates an instance of this class and uses this class to construct + /// a list of tokens to parse. + /// + public class LexicalAnalyzer + { + + /// + /// Starts the tokenization of the string ToTokenize and returns the tokenization as a FIFO Queue + /// This method will throw exceptions when necessary input isn't useable: + /// + /// Thrown when the Tokenize method is called and there are + /// no TokenDefinitions found + /// The string which has to be tokenized. If stringToTokenize is empty, an empty Queue object + /// is returned. + /// Flag to signal the tokenizer to remove overlapped tokens found. This is necessary + /// when your parser logic shouldn't be bothered with overlapped tokens, like: (UBB syntaxis + strings) "this [b]is[/b] overlapping" + /// will result in a string token (if specified) and 2 tokens of the UBB syntax: [b] and [/b]. If you don't want these last + /// 2 tokens to appear, since they're included in another token, the string token, set removeOverlappedTokens to true + /// Queue with the tokens or null if an internal error occured. + public Queue Tokenize(string stringToTokenize, bool removeOverlappedTokens) + { + Queue resultTokenList; // Queue list of IToken objects. + + try + { + // initialize and start tokenizer + Tokenizer tokenizerObject = new Tokenizer(); + tokenizerObject.ToTokenize = stringToTokenize; + tokenizerObject.RemoveOverlappedTokens = removeOverlappedTokens; + + // start it. + resultTokenList = tokenizerObject.Tokenize(); + + // return result + return resultTokenList; + } + catch(NoTokenDefinitionsSpecifiedException) + { + // bubble + throw; + } + catch + { + // other error, return null + return null; + } + } + } +} diff --git a/UBBParser/UBBParser/NonTerminal.cs b/UBBParser/UBBParser/NonTerminal.cs new file mode 100644 index 0000000..86f3afa --- /dev/null +++ b/UBBParser/UBBParser/NonTerminal.cs @@ -0,0 +1,94 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections.Generic; + +namespace SD.HnD.UBBParser +{ + /// + /// Generic implementation of a NonTerminal object, which is a result of + /// the token parse process. + /// + public class NonTerminal + { + #region Class Member Declarations + private List _tokens; // List which holds all the tokens which form this nonterminal. + private NonTerminalType _type; + private int _correspondingEndNTIndex; + #endregion + + + /// + /// CTor + /// + /// The type of this nonterminal + public NonTerminal(NonTerminalType typeOfNonTerminal) + { + _type = typeOfNonTerminal; + _tokens = new List(); + } + + + #region Class Property Declarations + /// + /// Gets / sets correspondingEndNTIndex. THis is the index of the corresponding end NonTerminal of the current Non Terminal. + /// if the current nonterminal is an end nonterminal (CodeTextEnd, QuotedTextEnd etc.) or doesn't have an end NonTerminal, this index is the + /// same as the index of the current NonTerminal. The index is the index in the parserResult list of nonterminals. + /// + public virtual int CorrespondingEndNTIndex + { + get + { + return _correspondingEndNTIndex; + } + set + { + _correspondingEndNTIndex = value; + } + } + + /// + /// Gets the token collection. + /// + public List Tokens + { + get + { + return _tokens; + } + } + + /// + /// Gets / sets the nonterminal type + /// + public NonTerminalType Type + { + get + { + return _type; + } + set + { + _type = value; + } + } + #endregion + } +} diff --git a/UBBParser/UBBParser/Parser.cs b/UBBParser/UBBParser/Parser.cs new file mode 100644 index 0000000..5513bb5 --- /dev/null +++ b/UBBParser/UBBParser/Parser.cs @@ -0,0 +1,1281 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml; + +namespace SD.HnD.UBBParser +{ + /// + /// UBB Parser. Parses the input passed in into tokens which are interpreted by the UBB Interpreter + /// + public class Parser + { + #region Static member declarations + /// + /// Static declared tokendefinition collection. As token regex objects are threadsafe, re-creating them is not necessary. + /// + public static List TokenDefinitions = new List(); + #endregion + + #region Class Member Declarations + private List _nonTerminalStream; + private string _stringToParse; + private Queue _tokenStream; + private Dictionary> _startNTStacks; // per non-terminal which needs it, there's a stack of start nonterminals for matching end NTs + #endregion + + + /// + /// Initializes the class' static members, which is the tokendefinition collection + /// + static Parser() + { + CreateTokenDefinitions(); + } + + + /// + /// CTor + /// + /// the text string to parse. + public Parser(string stringToParse) + { + _nonTerminalStream = new List(); + _stringToParse = stringToParse; + _startNTStacks = new Dictionary>(); + } + + + /// + /// Starts the parse process + /// + /// List object with nonterminal objects. This can be fed to the interpreter. + public List StartParseProcess() + { + _nonTerminalStream.Clear(); + _startNTStacks.Clear(); + + // tokenize the string + LexicalAnalyzer lex = new LexicalAnalyzer(); + _tokenStream = lex.Tokenize(_stringToParse, true); + + // parse the tokenstream into _nonTerminals for the interpreter. + ParseTokens(); + return _nonTerminalStream; + } + + + /// + /// Parses the token stream into nonterminal objects. Uses simple LL(1) algo. + /// Fills _nonTerminalStream; + /// + private void ParseTokens() + { + IToken literalTextToken = null; + + // parse the tokens + bool eofFound = false; + while((_tokenStream.Count > 0)&&!eofFound) + { + IToken currentToken = (IToken)_tokenStream.Peek(); + + int index = 0; + switch((Token)currentToken.TokenID) + { + case Token.EOF: + // done + eofFound = true; + break; + case Token.BoldTextStartTag: + case Token.BoldTextEndTag: + case Token.CodeTextStartTag: + case Token.CodeTextEndTag: + case Token.ColoredTextStartTag: + case Token.ColoredTextEndTag: + case Token.LF: + case Token.EmailAddress: + case Token.ImageStartTag: + case Token.ImageURL: + case Token.ItalicTextStartTag: + case Token.ItalicTextEndTag: + case Token.ListEndTag: + case Token.ListItemEndTag: + case Token.ListItemStartTag: + case Token.ListStartTag: + case Token.OfftopicTextStartTag: + case Token.OfftopicTextEndTag: + case Token.QuotedTextStartTag: + case Token.QuotedTextEndTag: + case Token.SizedTextStartTag: + case Token.SizedTextEndTag: + case Token.SmileyLaugh: + case Token.SmileyAngry: + case Token.SmileyRegular: + case Token.SmileyWink: + case Token.SmileyCool: + case Token.SmileyTongue: + case Token.SmileyConfused: + case Token.SmileyShocked: + case Token.SmileyDissapointed: + case Token.SmileySad: + case Token.SmileyEmbarrassed: + case Token.StrikedTextStartTag: + case Token.StrikedTextEndTag: + case Token.Tab: + case Token.UnderlinedTextStartTag: + case Token.UnderlinedTextEndTag: + case Token.URLStartTag: + case Token.URI: + // Tag or otherwise nonterminal start. Handle statement. First create new nonterminal with current collected text, if available. + if(literalTextToken!=null) + { + NonTerminal scannedText = new NonTerminal(NonTerminalType.LiteralText); + scannedText.Tokens.Add(literalTextToken); + literalTextToken=null; + + _nonTerminalStream.Add(scannedText); + index = (_nonTerminalStream.Count - 1); + scannedText.CorrespondingEndNTIndex=index; + } + + // token is still in the queue. + NonTerminal parsedNonTerminal = ParseNonTerminal(); + _nonTerminalStream.Add(parsedNonTerminal); + index = (_nonTerminalStream.Count - 1); + parsedNonTerminal.CorrespondingEndNTIndex = index; + Stack ntStack = null; + switch(parsedNonTerminal.Type) + { + case NonTerminalType.BoldTextEnd: + ntStack = GetStartNTStack(NonTerminalType.BoldTextStart); + break; + case NonTerminalType.CodeTextEnd: + ntStack = GetStartNTStack(NonTerminalType.CodeTextStart); + break; + case NonTerminalType.ColoredTextEnd: + ntStack = GetStartNTStack(NonTerminalType.ColoredTextStart); + break; + case NonTerminalType.ItalicTextEnd: + ntStack = GetStartNTStack(NonTerminalType.ItalicTextStart); + break; + case NonTerminalType.ListItemEnd: + ntStack = GetStartNTStack(NonTerminalType.ListItemStart); + break; + case NonTerminalType.ListEnd: + ntStack = GetStartNTStack(NonTerminalType.ListStart); + break; + case NonTerminalType.OfftopicTextEnd: + ntStack = GetStartNTStack(NonTerminalType.OfftopicTextStart); + break; + case NonTerminalType.QuotedTextEnd: + ntStack = GetStartNTStack(NonTerminalType.QuotedTextStart); + break; + case NonTerminalType.SizedTextEnd: + ntStack = GetStartNTStack(NonTerminalType.SizedTextStart); + break; + case NonTerminalType.StrikedTextEnd: + ntStack = GetStartNTStack(NonTerminalType.StrikedTextStart); + break; + case NonTerminalType.UnderlinedTextEnd: + ntStack = GetStartNTStack(NonTerminalType.UnderlinedTextStart); + break; + } + if((ntStack!=null) && (ntStack.Count > 0)) + { + NonTerminal startNT = ntStack.Pop(); + startNT.CorrespondingEndNTIndex = index; + } + + break; + case Token.CR: + // skip. We only use LF tokens for linefeeds. + _tokenStream.Dequeue(); + break; + case Token.ImageEndTag: + case Token.URLEndTag: + default: + // literal text or token which isn't defined properly. Push the complete text as + // literal text into the current literal text token. + currentToken = _tokenStream.Dequeue(); + if(literalTextToken==null) + { + literalTextToken = new UBBToken(); + literalTextToken.RelatedTokenDefinition = Parser.TokenDefinitions[(int)Token.UntokenizedLiteralString]; + } + literalTextToken.LiteralMatchedTokenText += currentToken.LiteralMatchedTokenText; + break; + } + } + + // handle resulting text which is processed but is not transformed to a nonterminal yet. + if(literalTextToken!=null) + { + NonTerminal scannedText = new NonTerminal(NonTerminalType.LiteralText); + scannedText.Tokens.Add(literalTextToken); + literalTextToken=null; + + _nonTerminalStream.Add(scannedText); + int index = (_nonTerminalStream.Count - 1); + scannedText.CorrespondingEndNTIndex=index; + } + + // change all nonterminals still on one of the stacks into literal text statements, since there are no matching endtokens found. + foreach(Stack startNTStack in _startNTStacks.Values) + { + foreach(NonTerminal current in startNTStack) + { + current.Type = NonTerminalType.LiteralText; + } + } + } + + + /// + /// Parses the current statement at the head of the token stream. It assumes the + /// statement start token is still at the start of the stream. + /// + /// + /// Filled NonTerminal object with the data of the statement parsed. + /// + private NonTerminal ParseNonTerminal() + { + List tokensInStatement = new List(); + + NonTerminal toReturn = new NonTerminal(NonTerminalType.LiteralText); + + // peek at the current token at the start of the stream. Do not pop it, it's thus not yet + // removed from the stream. + IToken currentToken = _tokenStream.Peek(); + + // check which statement we're looking at. + switch((Token)currentToken.TokenID) + { + case Token.ColoredTextStartTag: + toReturn = HandleColoredTextStart(tokensInStatement); + break; + case Token.ImageStartTag: + toReturn = HandleImageStart(tokensInStatement); + break; + case Token.ListStartTag: + toReturn = HandleListStart(tokensInStatement); + break; + case Token.QuotedTextStartTag: + toReturn = HandleQuotedTextStart(tokensInStatement); + break; + case Token.SizedTextStartTag: + toReturn = HandleSizedTextStart(tokensInStatement); + break; + case Token.URLStartTag: + toReturn = HandleURLStart(tokensInStatement); + break; + case Token.BoldTextStartTag: + case Token.BoldTextEndTag: + case Token.CodeTextStartTag: + case Token.CodeTextEndTag: + case Token.ColoredTextEndTag: + case Token.LF: + case Token.EmailAddress: + case Token.ImageURL: + case Token.ItalicTextStartTag: + case Token.ItalicTextEndTag: + case Token.ListEndTag: + case Token.ListItemEndTag: + case Token.ListItemStartTag: + case Token.OfftopicTextStartTag: + case Token.OfftopicTextEndTag: + case Token.QuotedTextEndTag: + case Token.SizedTextEndTag: + case Token.SmileyLaugh: + case Token.SmileyAngry: + case Token.SmileyRegular: + case Token.SmileyWink: + case Token.SmileyCool: + case Token.SmileyTongue: + case Token.SmileyConfused: + case Token.SmileyShocked: + case Token.SmileyDissapointed: + case Token.SmileySad: + case Token.SmileyEmbarrassed: + case Token.StrikedTextStartTag: + case Token.StrikedTextEndTag: + case Token.Tab: + case Token.UnderlinedTextStartTag: + case Token.UnderlinedTextEndTag: + case Token.URI: + // single token tag + toReturn = HandleSingleTokenTag(tokensInStatement); + break; + case Token.CR: + // skip + break; + default: + // error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + break; + } + + return toReturn; + } + + + /// + /// Handles the URL start tokens and converts them into a nontermimal, if the syntax is correct. + /// + /// The tokens in statement. + /// + private NonTerminal HandleURLStart(List tokensInStatement) + { + // first token has to be '[url', this routine gets called when the current token is [url + if(!TestCurrentToken(Token.URLStartTag, "HandleURLStart", true)) + { + // failed. Exception is thrown by TestCurrentToken + } + + // if is in the queue. Pop it. + IToken currentToken = _tokenStream.Dequeue(); + tokensInStatement.Add(currentToken); + + // we're inside a tag, therefor we can throw away whitespace. + StripWhiteSpace(); + + NonTerminal toReturn = new NonTerminal(NonTerminalType.URLStart); + + // Next token is either tag end, or descriptionterminal. + currentToken = (IToken)_tokenStream.Peek(); + switch((Token)currentToken.TokenID) + { + case Token.TagCloseBracket: + // valid argument. Pop it. + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + case Token.DescriptionTerminal: + // description specified. Assignment and quoted string have to follow. + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + // next token has to he assignment. + + if(!TestCurrentToken(Token.Assignment, "HandleURLStart", false)) + { + // not an assignment seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // assignment seen. Pop it + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + if(!TestCurrentToken(Token.QuotedString, "HandleURLStart", false)) + { + // not a quoted string seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + // next token has to be a tagclosebracket + StripWhiteSpace(); + if(!TestCurrentToken(Token.TagCloseBracket, "HandleURLStart", false)) + { + // not an endbracket seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + default: + // error + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // now strip whitespace and continue parsing. + StripWhiteSpace(); + // next token has to be an URI or ImageURL + if((!TestCurrentToken(Token.URI, "HandleURLStart", false)) && (!TestCurrentToken(Token.ImageURL, "HandleURLStart", false))) + { + // not an URI / ImageURL seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + StripWhiteSpace(); + // now an urlend tag has to be there + if(!TestCurrentToken(Token.URLEndTag, "HandleURLStart", false)) + { + // not an url end tag seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + // done + toReturn.Tokens.AddRange(tokensInStatement); + return toReturn; + } + + + /// + /// Handles the Sized start tokens and converts them into a nontermimal, if the syntax is correct. + /// + /// The tokens in statement. + /// + private NonTerminal HandleSizedTextStart(List tokensInStatement) + { + // first token has to be '[size', this routine gets called when the current token is [size + if(!TestCurrentToken(Token.SizedTextStartTag, "HandleSizedTextStart", true)) + { + // failed. Exception is thrown by TestCurrentToken + } + + // if is in the queue. Pop it. + IToken currentToken = _tokenStream.Dequeue(); + tokensInStatement.Add(currentToken); + + // we're inside a tag, therefor we can throw away whitespace. + StripWhiteSpace(); + + NonTerminal toReturn = new NonTerminal(NonTerminalType.SizedTextStart); + + // Next token has to be valueTerminal. + currentToken = (IToken)_tokenStream.Peek(); + switch((Token)currentToken.TokenID) + { + case Token.ValueTerminal: + // value specified. Assignment and (single) quoted string have to follow. + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // next token has to he assignment. + if(!TestCurrentToken(Token.Assignment, "HandleSizedTextStart", false)) + { + // not an assignment seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // assignment seen. Pop it + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // next token either is a quoted string or a single quoted string. + currentToken = (IToken)_tokenStream.Peek(); + switch((Token)currentToken.TokenID) + { + case Token.QuotedString: + case Token.SingleQuotedNumericString: + // valid + break; + default: + // error + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + // next token has to be a tagclosebracket + StripWhiteSpace(); + if(!TestCurrentToken(Token.TagCloseBracket, "HandleSizedTextStart", false)) + { + // not an endbracket seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + default: + // error + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // done + toReturn.Tokens.AddRange(tokensInStatement); + + // store this nonterminal onto its stack so a matching end tag can be linked with it. + Stack stack = GetStartNTStack(NonTerminalType.SizedTextStart); + stack.Push(toReturn); + + return toReturn; + } + + + /// + /// Handles the Quoted start tokens and converts them into a nontermimal, if the syntax is correct. + /// + /// The tokens in statement. + /// + private NonTerminal HandleQuotedTextStart(List tokensInStatement) + { + // first token has to be '[quote', this routine gets called when the current token is [quote + if(!TestCurrentToken(Token.QuotedTextStartTag, "HandleQuotedTextStart", true)) + { + // failed. Exception is thrown by TestCurrentToken + } + + // if is in the queue. Pop it. + IToken currentToken = _tokenStream.Dequeue(); + tokensInStatement.Add(currentToken); + + // we're inside a tag, therefor we can throw away whitespace. + StripWhiteSpace(); + + NonTerminal toReturn = new NonTerminal(NonTerminalType.QuotedTextStart); + + // Next token is either tag end, or nickterminal. + currentToken = (IToken)_tokenStream.Peek(); + switch((Token)currentToken.TokenID) + { + case Token.TagCloseBracket: + // valid argument. Pop it. + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + case Token.NickTerminal: + // Nick terminal specified. Assignment and quoted string have to follow. + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // next token has to he assignment. + if(!TestCurrentToken(Token.Assignment, "HandleQuotedTextStart", false)) + { + // not an assignment seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // assignment seen. Pop it + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // quoted string has to follow + if(!TestCurrentToken(Token.QuotedString, "HandleQuotedTextStart", false)) + { + // not a quoted string seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + // next token has to be a tagclosebracket + StripWhiteSpace(); + if(!TestCurrentToken(Token.TagCloseBracket, "HandleQuotedTextStart", false)) + { + // not an endbracket seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + default: + // error + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // done + toReturn.Tokens.AddRange(tokensInStatement); + + // store this nonterminal onto its stack so a matching end tag can be linked with it. + Stack stack = GetStartNTStack(NonTerminalType.QuotedTextStart); + stack.Push(toReturn); + return toReturn; + } + + + /// + /// Handles the List start tokens and converts them into a nontermimal, if the syntax is correct. + /// + /// The tokens in statement. + /// + private NonTerminal HandleListStart(List tokensInStatement) + { + // first token has to be '[list', this routine gets called when the current token is [list + if(!TestCurrentToken(Token.ListStartTag, "HandleListStart", true)) + { + // failed. Exception is thrown by TestCurrentToken + } + + // if is in the queue. Pop it. + IToken currentToken = _tokenStream.Dequeue(); + tokensInStatement.Add(currentToken); + + // we're inside a tag, therefor we can throw away whitespace. + StripWhiteSpace(); + + NonTerminal toReturn = new NonTerminal(NonTerminalType.ListStart); + + // Next token is either tag end, or typeterminal. + currentToken = (IToken)_tokenStream.Peek(); + switch((Token)currentToken.TokenID) + { + case Token.TagCloseBracket: + // valid argument. Pop it. + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + case Token.TypeTerminal: + // type terminal specified. Assignment and quoted string have to follow. + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // next token has to he assignment. + if(!TestCurrentToken(Token.Assignment, "HandleListStart", false)) + { + // not an assignment seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // assignment seen. Pop it + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // quoted string has to follow + if(!TestCurrentToken(Token.QuotedString, "HandleListStart", false)) + { + // not a quoted string seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + // next token has to be a tagclosebracket + StripWhiteSpace(); + if(!TestCurrentToken(Token.TagCloseBracket, "HandleListStart", false)) + { + // not an endbracket seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + default: + // error + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // done + toReturn.Tokens.AddRange(tokensInStatement); + + // store this nonterminal onto its stack so a matching end tag can be linked with it. + Stack stack = GetStartNTStack(NonTerminalType.ListStart); + stack.Push(toReturn); + return toReturn; + } + + + /// + /// Handles the Image start tokens and converts them into a nontermimal, if the syntax is correct. + /// + /// The tokens in statement. + /// + /// Handles the complete [img...]...[/img] sequence + private NonTerminal HandleImageStart(List tokensInStatement) + { + // first token has to be '[img', this routine gets called when the current token is [img + if(!TestCurrentToken(Token.ImageStartTag, "HandleImageStart", true)) + { + // failed. Exception is thrown by TestCurrentToken + } + + // if is in the queue. Pop it. + IToken currentToken = _tokenStream.Dequeue(); + tokensInStatement.Add(currentToken); + + // we're inside a tag, therefor we can throw away whitespace. + StripWhiteSpace(); + + NonTerminal toReturn = new NonTerminal(NonTerminalType.ImageStart); + + // Next token is either tag end, or altterminal. + currentToken = (IToken)_tokenStream.Peek(); + switch((Token)currentToken.TokenID) + { + case Token.TagCloseBracket: + // valid argument. Pop it. + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + case Token.AltTerminal: + // alt terminal specified. Assignment and quoted string have to follow. + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // next token has to he assignment. + if(!TestCurrentToken(Token.Assignment, "HandleImageStart", false)) + { + // not an assignment seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // assignment seen. Pop it + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // quoted string has to follow + if(!TestCurrentToken(Token.QuotedString, "HandleImageStart", false)) + { + // not a quoted string seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + // next token has to be a tagclosebracket + StripWhiteSpace(); + if(!TestCurrentToken(Token.TagCloseBracket, "HandleImageStart", false)) + { + // not an endbracket seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + default: + // error + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // now strip whitespace and continue parsing. + StripWhiteSpace(); + // next token has to be an ImageURL + if(!TestCurrentToken(Token.ImageURL, "HandleImageStart", false)) + { + // not an imageurl seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + StripWhiteSpace(); + // now an imageend tag has to be there + if(!TestCurrentToken(Token.ImageEndTag, "HandleImageStart", false)) + { + // not an image end tag seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + // done + toReturn.Tokens.AddRange(tokensInStatement); + return toReturn; + } + + + /// + /// Handles the Color start tokens and converts them into a nontermimal, if the syntax is correct. + /// + /// The tokens in statement. + /// + private NonTerminal HandleColoredTextStart(List tokensInStatement) + { + // first token has to be '[size', this routine gets called when the current token is [size + if(!TestCurrentToken(Token.ColoredTextStartTag, "HandleColoredTextStart", true)) + { + // failed. Exception is thrown by TestCurrentToken + } + + // if is in the queue. Pop it. + IToken currentToken = _tokenStream.Dequeue(); + tokensInStatement.Add(currentToken); + + // we're inside a tag, therefor we can throw away whitespace. + StripWhiteSpace(); + + NonTerminal toReturn = new NonTerminal(NonTerminalType.ColoredTextStart); + + // Next token has to be valueTerminal. + currentToken = (IToken)_tokenStream.Peek(); + switch((Token)currentToken.TokenID) + { + case Token.ValueTerminal: + // value specified. Assignment and (single) quoted string have to follow. + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // next token has to he assignment. + if(!TestCurrentToken(Token.Assignment, "HandleColoredTextStart", false)) + { + // not an assignment seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // assignment seen. Pop it + tokensInStatement.Add(_tokenStream.Dequeue()); + StripWhiteSpace(); + + // quoted string has to follow + if(!TestCurrentToken(Token.QuotedString, "HandleColoredTextStart", false)) + { + // not a quoted string seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + + // next token has to be a tagclosebracket + StripWhiteSpace(); + if(!TestCurrentToken(Token.TagCloseBracket, "HandleColoredTextStart", false)) + { + // not an endbracket seen. Error. + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + tokensInStatement.Add(_tokenStream.Dequeue()); + break; + default: + // error + toReturn = ConvertPoppedTokensToLiteralText(tokensInStatement); + // return now. + return toReturn; + } + // done + toReturn.Tokens.AddRange(tokensInStatement); + + // store this nonterminal onto its stack so a matching end tag can be linked with it. + Stack stack = GetStartNTStack(NonTerminalType.ColoredTextStart); + stack.Push(toReturn); + + return toReturn; + } + + + /// + /// Handles the StatementStart single-token-statement-token StatementEnd statement + /// + /// Tokens already scanned + /// Filled NonTerminal with the tokens scanned. If there were no errors, this nonterminal will be + /// of type EndIf. If there were errors, this nonterminal will be of type literaltext. + private NonTerminal HandleSingleTokenTag(List tokensInStatement) + { + NonTerminal toReturn = null; + + // store this nonterminal onto its stack so a matching end tag can be linked with it. + Stack ntStack = null; + + IToken currentToken = (IToken)_tokenStream.Peek(); + switch((Token)currentToken.TokenID) + { + case Token.BoldTextStartTag: + toReturn = new NonTerminal(NonTerminalType.BoldTextStart); + ntStack = GetStartNTStack(toReturn.Type); + break; + case Token.BoldTextEndTag: + toReturn = new NonTerminal(NonTerminalType.BoldTextEnd); + break; + case Token.CodeTextStartTag: + toReturn = new NonTerminal(NonTerminalType.CodeTextStart); + ntStack = GetStartNTStack(toReturn.Type); + break; + case Token.CodeTextEndTag: + toReturn = new NonTerminal(NonTerminalType.CodeTextEnd); + break; + case Token.ColoredTextEndTag: + toReturn = new NonTerminal(NonTerminalType.ColoredTextEnd); + break; + case Token.LF: + toReturn = new NonTerminal(NonTerminalType.CRLF); + break; + case Token.EmailAddress: + toReturn = new NonTerminal(NonTerminalType.EmailAddress); + break; + case Token.ImageURL: + toReturn = new NonTerminal(NonTerminalType.ImageURL); + break; + case Token.ItalicTextStartTag: + toReturn = new NonTerminal(NonTerminalType.ItalicTextStart); + ntStack = GetStartNTStack(toReturn.Type); + break; + case Token.ItalicTextEndTag: + toReturn = new NonTerminal(NonTerminalType.ItalicTextEnd); + break; + case Token.ListEndTag: + toReturn = new NonTerminal(NonTerminalType.ListEnd); + break; + case Token.ListItemEndTag: + toReturn = new NonTerminal(NonTerminalType.ListItemEnd); + break; + case Token.ListItemStartTag: + toReturn = new NonTerminal(NonTerminalType.ListItemStart); + ntStack = GetStartNTStack(toReturn.Type); + break; + case Token.OfftopicTextStartTag: + toReturn = new NonTerminal(NonTerminalType.OfftopicTextStart); + ntStack = GetStartNTStack(toReturn.Type); + break; + case Token.OfftopicTextEndTag: + toReturn = new NonTerminal(NonTerminalType.OfftopicTextEnd); + break; + case Token.QuotedTextEndTag: + toReturn = new NonTerminal(NonTerminalType.QuotedTextEnd); + break; + case Token.SizedTextEndTag: + toReturn = new NonTerminal(NonTerminalType.SizedTextEnd); + break; + case Token.SmileyLaugh: + toReturn = new NonTerminal(NonTerminalType.SmileyLaugh); + break; + case Token.SmileyAngry: + toReturn = new NonTerminal(NonTerminalType.SmileyAngry); + break; + case Token.SmileyRegular: + toReturn = new NonTerminal(NonTerminalType.SmileyRegular); + break; + case Token.SmileyWink: + toReturn = new NonTerminal(NonTerminalType.SmileyWink); + break; + case Token.SmileyCool: + toReturn = new NonTerminal(NonTerminalType.SmileyCool); + break; + case Token.SmileyTongue: + toReturn = new NonTerminal(NonTerminalType.SmileyTongue); + break; + case Token.SmileyConfused: + toReturn = new NonTerminal(NonTerminalType.SmileyConfused); + break; + case Token.SmileyShocked: + toReturn = new NonTerminal(NonTerminalType.SmileyShocked); + break; + case Token.SmileyDissapointed: + toReturn = new NonTerminal(NonTerminalType.SmileyDissapointed); + break; + case Token.SmileySad: + toReturn = new NonTerminal(NonTerminalType.SmileySad); + break; + case Token.SmileyEmbarrassed: + toReturn = new NonTerminal(NonTerminalType.SmileyEmbarrassed); + break; + case Token.StrikedTextStartTag: + toReturn = new NonTerminal(NonTerminalType.StrikedTextStart); + ntStack = GetStartNTStack(toReturn.Type); + break; + case Token.StrikedTextEndTag: + toReturn = new NonTerminal(NonTerminalType.StrikedTextEnd); + break; + case Token.Tab: + toReturn = new NonTerminal(NonTerminalType.Tab); + break; + case Token.UnderlinedTextStartTag: + toReturn = new NonTerminal(NonTerminalType.UnderlinedTextStart); + ntStack = GetStartNTStack(toReturn.Type); + break; + case Token.UnderlinedTextEndTag: + toReturn = new NonTerminal(NonTerminalType.UnderlinedTextEnd); + break; + case Token.URI: + toReturn = new NonTerminal(NonTerminalType.URI); + break; + default: + // error. This error is only caused by an internal parser error + throw new ApplicationException("Internal parser error detected. 'HandleSingleStatement' expected a singel statement token but received token '" + ((IToken)_tokenStream.Peek()).TokenID.ToString() + "'."); + } + + tokensInStatement.Add(_tokenStream.Dequeue()); + toReturn.Tokens.AddRange(tokensInStatement); + + if(ntStack != null) + { + // push nonterminal as start nonterminal onto its stack so a related end nonterminal can relate to it. + ntStack.Push(toReturn); + } + + return toReturn; + } + + + /// + /// Tests the current token on the stack if it is the token passed in as tokenToTest. If so, true is returned. + /// If not, false is returned. If testCantFail is true, the caller assumes a token at the start of the queue. If that's + /// not the case, an internal parser error has been detected and an exception is thrown. The token at the start of the queue + /// is not popped from the queue. + /// + /// Token which should be the first token in the queue + /// name of the caller of this method. Used in the exception thrown when an internal parser error + /// is detected + /// flag to signal if failure of the test results in an internal parser error + /// true if the token at the start of the queue is equal to tokenToTest, false otherwise + /// When testCantFail is true and the test fails. + private bool TestCurrentToken(Token tokenToTest, string nameCaller, bool testCantFail) + { + return TestCurrentToken(tokenToTest, nameCaller, testCantFail, _tokenStream); + } + + + /// + /// Tests the current token on the stack if it is the token passed in as tokenToTest. If so, true is returned. + /// If not, false is returned. If testCantFail is true, the caller assumes a token at the start of the queue. If that's + /// not the case, an internal parser error has been detected and an exception is thrown. The token at the start of the queue + /// is not popped from the queue. + /// + /// Token which should be the first token in the queue + /// name of the caller of this method. Used in the exception thrown when an internal parser error + /// is detected + /// flag to signal if failure of the test results in an internal parser error + /// token queue to test + /// true if the token at the start of the queue is equal to tokenToTest, false otherwise + /// When testCantFail is true and the test fails. + private bool TestCurrentToken(Token tokenToTest, string nameCaller, bool testCantFail, Queue tokens) + { + bool toReturn = (tokens.Peek().TokenID==(int)tokenToTest); + if((!toReturn)&&testCantFail) + { + // internal parser error + throw new ApplicationException("Internal parser error detected. '" + nameCaller + "' expected token '" + tokenToTest.ToString() + "' but received token '" + ((Token)((IToken)tokens.Peek()).TokenID).ToString() + "'."); + } + + return toReturn; + } + + + /// + /// Converts the passed in set of popped tokens to one nonterminal of type LiteralText. This + /// routine is used when an error is found in the stream so the currently popped tokens are + /// apparantly not part of a statement, therefor should be converted to a literal string nonterminal, + /// which will be transformed by the interpreter as a textstream. The error causing token is not included + /// in the tokensPopped collection. + /// + /// Set of tokens popped, EXCLUDING the error causing token, which will be used as one set + /// of tokens of one nonterminal of type literal text + /// the literal text nonterminal with all the tokens passed in. + private NonTerminal ConvertPoppedTokensToLiteralText(List tokensPopped) + { + NonTerminal toReturn = new NonTerminal(NonTerminalType.LiteralText); + + IToken literalTextToken = new UBBToken(); + literalTextToken.RelatedTokenDefinition = Parser.TokenDefinitions[(int)Token.UntokenizedLiteralString]; + + IToken currentToken = null; + for(int i=0;i + /// Will remove all tokens which are considered whitespace from the tokenstream. + /// These are the tokens: + /// 'WhiteSpace'. + /// + private void StripWhiteSpace() + { + StripWhiteSpace(_tokenStream); + } + + + /// + /// Will remove all tokens which are considered whitespace from the tokenstream passed in + /// These are the tokens: + /// 'WhiteSpace'. + /// + private void StripWhiteSpace(Queue toStrip) + { + // loop through the whitespace tokens. Will stop at the end of the stream or when another token + // is 'seen'. + while(toStrip.Peek().TokenID==(int)Token.WhiteSpace) + { + // pop token and get rid of it. + IToken popped = toStrip.Dequeue(); + } + } + + + /// + /// Create the tokendefinitions. Tokendefinitions are regular expressions which match a textsnippet so the snippet can be represented by the token + /// + private static void CreateTokenDefinitions() + { + // EOF, Mandatory token + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.EOF, "", RegexOptions.None)); + // Untokenized string. Mandatory token. + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.UntokenizedLiteralString, "", RegexOptions.None)); + // alt token (Alt) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.AltTerminal, @"alt", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // '=' token (Assignment) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.Assignment, @"=", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [b] token (BoldTextStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.BoldTextStartTag, @"\[b\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/b] token (BoldTextEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.BoldTextEndTag, @"\[/b\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [code token (CodeTextStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.CodeTextStartTag, @"\[code]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/code] token (CodeTextEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.CodeTextEndTag, @"\[/code\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [color token (ColorStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ColoredTextStartTag, @"\[color", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/color] token (ColorEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ColoredTextEndTag, @"\[/color]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // \r token (CR) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.CR, @"\r", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // description token (Description) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.DescriptionTerminal, @"description", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // Emailaddress token (EmailAddress) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.EmailAddress, @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [img token (ImageStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ImageStartTag, @"\[img", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/img] token (ImageEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ImageEndTag, @"\[/img\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ImageURL token (ImageURL). + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ImageURL, @"(http://www.|http://)([\w-]+\.)+[\w-]+(/[\w-./?%&+,#;~=]*)?/[\w-]+\.(jpg|gif|png)", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [i] token (ItalicTextStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ItalicTextStartTag, @"\[i\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/i] token (ItalicTextEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ItalicTextEndTag, @"\[/i\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [*] token (ListItemStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ListItemStartTag, @"\[\*\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/*] token (ListItemEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ListItemEndTag, @"\[/\*\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/list] token (ListEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ListEndTag, @"\[/list\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [list token (ListStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ListStartTag, @"\[list", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // \n token (LF) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.LF, @"\n", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // 'nick' token (Nick) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.NickTerminal, @"nick", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [offtopic] token (OfftopicTextStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.OfftopicTextStartTag, @"\[offtopic\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/offtopic] token (OfftopicTextEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.OfftopicTextEndTag, @"\[/offtopic\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // QuotedString token + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.QuotedString, "(\".*?\")", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [quote token (QuoteTextStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.QuotedTextStartTag, @"\[quote", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/quote] token (QuoteTextEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.QuotedTextEndTag, @"\[/quote\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [size token (SizeStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SizedTextStartTag, @"\[size", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/size] token (SizeEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SizedTextEndTag, @"\[/size\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [s] token (StrikedTextStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.StrikedTextStartTag, @"\[s\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/s] token (StrikedTextEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.StrikedTextEndTag, @"\[/s\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [u] token (UnderlinedTextStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.UnderlinedTextStartTag, @"\[u\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/u] token (UnderlinedTextEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.UnderlinedTextEndTag, @"\[/u\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // SingleQuotedString token + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SingleQuotedNumericString, @"('\d')", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ':D' token (SmileyLaugh) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyLaugh, @":D", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ':(' token (SmileyAngry) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyAngry, @":\(", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ':)' token (SmileyRegular) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyRegular, @":\)", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ';)' token (SmileyWink) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyWink, @";\)", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // '8)' token (SmileyCool) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyCool, @"8\)", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ':P' token (SmileyTongue) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyTongue, @":P", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ':?' token (SmileyConfused) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyConfused, @":\?", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ':o' token (SmileyShocked) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyShocked, @":o", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ':/' token (SmileyDissapointed) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyDissapointed, @":/", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ';(' token (SmileySad) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileySad, @";\(", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ':!' token (SmileyEmbarassed) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.SmileyEmbarrassed, @":\!", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ' ' (4 * space) or TAB + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.Tab, @"[ ]{4}|\t", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ']' token (TagCloseBracket) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.TagCloseBracket, @"\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // type token (Type) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.TypeTerminal, @"type", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // URI token (URI) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.URI, @"(http://www.|http://|https://www.|https://)([\w-]+\.)+[\w-]+(/[\w-./?%&+,~=#]*)?", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [url token (URLStartTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.URLStartTag, @"\[url", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // [/url] token (URLEndTag) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.URLEndTag, @"\[/url\]", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // value token (Value) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.ValueTerminal, @"value", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + // ' ' (space) + Parser.TokenDefinitions.Add(new UBBTokenDefinition((int)Token.WhiteSpace, @"[ ]{1,3}", RegexOptions.Compiled | RegexOptions.IgnoreCase)); + } + + + /// + /// Gets the start NT stack for the nonterminal type passed in. If the stack isn't available, a new one is created. + /// + /// Type of the nt. + /// + private Stack GetStartNTStack(NonTerminalType ntType) + { + Stack toReturn = null; + if(!_startNTStacks.TryGetValue(ntType, out toReturn)) + { + // create a new one + toReturn = new Stack(); + _startNTStacks.Add(ntType, toReturn); + } + + return toReturn; + } + + + #region Class Property Declarations + /// + /// Gets / sets stringToParse + /// + public string StringToParse + { + get + { + return _stringToParse; + } + set + { + _stringToParse = value; + } + } + #endregion + + } +} diff --git a/UBBParser/UBBParser/Tokenizer.cs b/UBBParser/UBBParser/Tokenizer.cs new file mode 100644 index 0000000..b670ae4 --- /dev/null +++ b/UBBParser/UBBParser/Tokenizer.cs @@ -0,0 +1,206 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace SD.HnD.UBBParser +{ + /// + /// Tokenizer class. This class tokenizes the given input using the given tokentables to a queue of tokens. + /// + internal class Tokenizer + { + #region Class Member Declarations + private string _stringToTokenize; // The input which has to be tokenized. + private ITokenDefinition _untokenizedLiteralStringToken; // The token definition for the UntokenizedLiteralString token. + private ITokenDefinition _eofToken; // The token definition for the EOF token. + private bool _removeOverlappedTokens; + #endregion + + + /// + /// CTor. + /// + public Tokenizer() + { + _stringToTokenize = String.Empty; + } + + + /// + /// Starts the tokenization of the value set into ToTokenize and will return a Queue with IToken objects + /// + /// Thrown when no TokenDefinition list is specified + /// Queue with IToken objects which represent a tokenized version of the inputstring ToTokenize + public Queue Tokenize() + { + if(Parser.TokenDefinitions == null) + { + throw new NoTokenDefinitionsSpecifiedException("No Token Definitions Found."); + } + + foreach(ITokenDefinition currentTokenDefinition in Parser.TokenDefinitions) + { + if(currentTokenDefinition.TokenID == (int)BuildInTokenID.UntokenizedLiteralString) + { + _untokenizedLiteralStringToken = currentTokenDefinition; + continue; + } + if(currentTokenDefinition.TokenID == (int)BuildInTokenID.EOF) + { + _eofToken = currentTokenDefinition; + continue; + } + } + + // all clear. Now walk all tokendefinitions for their regular expressions and collect MatchCollections of these + // regular expressions. Store all found tokens in a sorted list, with the starting char as the key. These will + // be then sorted on that key and based on the sorting result the result queue is build. When regular expressions + // are build badly, overlapping tokens can be found. The parser should be handling this. + + // create sorted list of result tokens + SortedList tokensFound = new SortedList(_stringToTokenize.Length / 10); + + // start the tokenization process + // walk all token definitions. Match all regular expressions with the string to tokenize. + // all matches are tokenized into tokens belonging with the token definition + // All tokens are then added to the sorted list with the index as the key + foreach(ITokenDefinition currentToken in Parser.TokenDefinitions) + { + if((currentToken.TokenID == (int)BuildInTokenID.UntokenizedLiteralString) || + (currentToken.TokenID == (int)BuildInTokenID.EOF)) + { + // skip this token definition + continue; + } + + MatchCollection matchesFound = currentToken.MatchingRegularExpression.Matches(_stringToTokenize); + if(matchesFound.Count > 0) + { + // found matches, convert the matches to tokens, if there is not already a token present at + // the current position. This is necessary since we're using regular expressions. + foreach(Match matchedSnippet in matchesFound) + { + // create a token using the factory object. TokenID and RelatedTokenDefinition are already filled in. + IToken toAdd = currentToken.CreateTokenFromDefinition(); + toAdd.LiteralMatchedTokenText = matchedSnippet.Value; + toAdd.StartIndexInInputStream = matchedSnippet.Index; + + if(!tokensFound.ContainsKey(matchedSnippet.Index)) + { + // no token found on this spot. Add it. + // add to sorted list + tokensFound.Add(matchedSnippet.Index, toAdd); + } + else + { + // it does have already a token on the spot. If that token is longer than the current token, + // keep it, otherwise replace the token with this token. + if(tokensFound[matchedSnippet.Index].LiteralMatchedTokenText.Length < toAdd.LiteralMatchedTokenText.Length) + { + tokensFound[matchedSnippet.Index] = toAdd; + } + } + } + } + } + + // now walk the resulted sorted list. Insert untokenizedliteralstring tokens for all unmatched characters in the + // inputstream. Do this at the same time as we transform the sorted list into a queue + Queue toReturn = new Queue(tokensFound.Count); + + int currentIndex = 0; + int firstIndexWithoutOverlap = 0; + //for(int i = 0; i < tokensFound.Count; i++) + foreach(KeyValuePair pair in tokensFound) + { + IToken currentToken = pair.Value; + + if(_removeOverlappedTokens) + { + // check if the index of this token falls inside another token. This is checked + // using iFirstIndxWithoutOverlap + if(currentToken.StartIndexInInputStream < firstIndexWithoutOverlap) + { + // this token is overlapped by another token. Skip it, it will then + // not be added to the queue + continue; + } + } + // check the index of the token with the current index. If there is a difference, the + // snippet formed by the difference is an UntokenizedLiteralString token. + if(currentIndex < currentToken.StartIndexInInputStream) + { + // there is difference, add an UntokenizedLiteralString token first. + IToken untokenizedLiteralString = _untokenizedLiteralStringToken.CreateTokenFromDefinition(); + untokenizedLiteralString.LiteralMatchedTokenText = _stringToTokenize.Substring(currentIndex, (currentToken.StartIndexInInputStream - currentIndex)); + untokenizedLiteralString.StartIndexInInputStream = currentIndex; + // add it directly to queue + toReturn.Enqueue(untokenizedLiteralString); + } + currentIndex = currentToken.StartIndexInInputStream + currentToken.LiteralMatchedTokenText.Length; + firstIndexWithoutOverlap = currentIndex; + toReturn.Enqueue(currentToken); + } + + // check if there is an unmatched snippet behind the last token found... + if(currentIndex < _stringToTokenize.Length) + { + // there is difference, add an UntokenizedLiteralString token first. + IToken untokenizedLiteralString = _untokenizedLiteralStringToken.CreateTokenFromDefinition(); + untokenizedLiteralString.LiteralMatchedTokenText = _stringToTokenize.Substring(currentIndex, (_stringToTokenize.Length - currentIndex)); + untokenizedLiteralString.StartIndexInInputStream = currentIndex; + // add it directly to queue + toReturn.Enqueue(untokenizedLiteralString); + } + + + // Add the EOF token, by definition token ID 0, to the queue at the end. + IToken eofToken = _eofToken.CreateTokenFromDefinition(); + toReturn.Enqueue(eofToken); + + // Done, return the queue + return toReturn; + } + + + #region Class Property Declarations + /// + /// If true, will remove encapsulated tokens found. For example ForEach contains 'For'. When RemoveOverlappedTokens is true, 'For' would + /// be removed as a found token. + /// + public bool RemoveOverlappedTokens + { + set { _removeOverlappedTokens = value; } + } + + /// + /// Sets the string to tokenize + /// + public string ToTokenize + { + set { _stringToTokenize = value; } + } + #endregion + + } +} diff --git a/UBBParser/UBBParser/UBBParser.csproj b/UBBParser/UBBParser/UBBParser.csproj new file mode 100644 index 0000000..0cd9819 --- /dev/null +++ b/UBBParser/UBBParser/UBBParser.csproj @@ -0,0 +1,199 @@ + + + Local + 8.0.50727 + 2.0 + {22A260C0-742F-42A7-82AB-DDB792082900} + Debug + AnyCPU + + + + + SD.HnD.UBBParser + + + JScript + Grid + IE50 + false + Library + SD.HnD.UBBParser + OnBuildSuccess + + + + + + + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE + bin\Release\SD.HnD.UBBParser.xml + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + bin\Release\ + false + 285212672 + false + + + TRACE + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Data + + + System.XML + + + + + Code + + + + Code + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + + + copy /y "$(TargetPath)" ..\..\..\..\ParserAssemblies\ + + \ No newline at end of file diff --git a/UBBParser/UBBParser/UBBSyntax.txt b/UBBParser/UBBParser/UBBSyntax.txt new file mode 100644 index 0000000..13c861f --- /dev/null +++ b/UBBParser/UBBParser/UBBSyntax.txt @@ -0,0 +1,240 @@ +UBB Syntax / grammar definition for the UBB SpecializedParser. + +Because the keywords use the '[]' characters, optional attributes are enclosed in +'<>' characters. These '<>' characters are not part of the attributes nor the tags. + +Available Keywords and their meaning +===================================== + +https://url, +http://url, +www.url, +foo@bar.com +will be recognized automatically. + +[img ]http://|https://url of image (gif/jpg/png)[/img] +[b]bold text[/b] +[i]italic text[/i] +[s]striked-through text[/s] +[u]underlined text[/u] +[url ]link[/url] +[sup]superscripted text[/sup] +[sub]subscripted text[/sub] +[quote ]text quoted[/quote] +[code]text which formatting should be preserved[/code] +[offtopic]offtopic text[/offtopic] +[list ] + [*]Item data +[/list] +[size value="1|2|3|4|5|6"]sized text[/size] +[color value="RRGGBB"]text in different color[/color] +all kinds of smileys: :) :( ;) :P :D :? :X etc. + + +Tokens +======== +[img ImageStartTag +alt AltTerminal += Assignment +"QuotedText" QuotedString +'QuotedText' SingleQuotedString +] TagCloseBracket +[/img] ImageEndTag +[b] BoldStartTag +[/b] BoldEndTag +[i] ItalicStartTag +[/i] ItalicEndTag +[s] StrikeStartTag +[/s] StrikeEndTag +[u] UnderlineStartTag +[/u] UnderlineEndTag +[url URLStartTag +description DescriptionTerminal +[/url] URLEndTag +[quote QuoteStartTag +[quote] QuoteStartTagSimple +nick NickTerminal +[/quote] QuoteEndTag +[code CodeStartTag +[/code] CodeEndTag +[offtopic] OfftopicStartTag +[/offtopic] OfftopicEndTag +[list ListStartTag +[list] ListStartTagSimple +type TypeTerminal +[*] ListItemStartTag +[/*] ListItemEndTag +[/list] ListEndTag +[size SizeStartTag +value ValueTerminal +[/size] SizeEndTag +[color ColorStartTag +[/color] ColorEndTag +A URL URL +A URL of an Image ImageURL +An emailaddress EmailAddress +:) etc. SmileyLaugh +UntokenizedString UntokenizedLiteralString + + +Grammar +========== +Tokenstrings are formulated between "''". These quotes are not part of the token, just +to distinguis them from the EBNF. Behind the RightHandSide (RHS) the XML tag is formulated which is +the result of the emitter. This tag is placed here between brackets (). ( RHS result ) means, that the +rule will emit the emitter result of the RHS's thus will not add any new information. () means the rule +will not emit anything at all. This is possible for close tags, since the XML dom will automatically +add close tags. All rules encapsulate their emitter contents in XmlDocumentFragments. + +0: StartSymbol -> GeneralText ( RHS result ) +1: GeneralText -> SpecialText GeneralText ( SpecialText Result Contents of RHS GeneralText ) +2: GeneralText -> SpecialText ( RHS result ) +3: SpecialText -> QuotedText ( RHS result ) +4: SpecialText -> CodeText ( RHS result ) +5: SpecialText -> FormattedText ( RHS result ) +6: SpecialText -> Image ( RHS result ) +7: SpecialText -> List ( RHS result ) +8: SpecialText -> URL ( RHS result ) +9: FormattedText -> FormattedTextElement FormattedText ( FormattedTextElement Result Contents of RHS FormattedText ) +10: FormattedText -> FormattedTextElement ( RHS Result ) +11: FormattedTextElement -> BoldText ( RHS result ) +12: FormattedTextElement -> ItalicText ( RHS result ) +13: FormattedTextElement -> StrikedText ( RHS result ) +14: FormattedTextElement -> UnderlinedText ( RHS result ) +15: FormattedTextElement -> OfftopicText ( RHS result ) +16: FormattedTextElement -> SizedText ( RHS result ) +17: FormattedTextElement -> ColoredText ( RHS result ) +18: FormattedTextElement -> LiteralTextElement ( RHS result ) +19: FormattedTextElement -> Smiley ( RHS result ) +20: FormattedTextElement -> EmailAddress ( RHS result ) +21: FormattedTextElement -> Link ( Link Result ) +22: LiteralText -> LiteralTextElement LiteralText ( LiteralTextElement Result Contents of RHS LiteralText ) +23: LiteralText -> LiteralTextElement ( LiteralTextElement Result ) +24: LiteralTextElement -> 'string of chars' ( RHS Result '[br]' (
    ) +26: QuotedText -> QuotedTextStart GeneralText QuotedTextEnd ( ... ) +27: QuotedTextStart -> '[quote ' 'nick' '=' QuotedString ']' ( ) +28: QuotedTextStart -> '[quote]' ( ) +29: QuotedTextEnd -> '[/quote]' () +30: CodeText -> CodeTextStart LiteralText CodeTextEnd ( LiteralText Result ) +31: CodeTextStart -> '[code]' ( ) +32: CodeTextEnd -> '[/code]' () +33: BoldText -> BoldTextStart FormattedText BoldTextEnd ( FormattedText Result ) +34: BoldTextStart -> '[b]' ( ) +35: BoldTextEnd -> '[/b]' () +36: ItalicText -> ItalicTextStart FormattedText ItalicTextEnd ( FormattedText Result ) +37: ItalicTextStart -> '[i]' ( ) +38: ItalicTextEnd -> '[/i]' () +39: StrikedText -> StrikedTextStart FormattedText StrikedTextEnd ( FormattedText Result ) +40: StrikedTextStart -> '[s]' ( ) +41: StrikedTextEnd -> '[/s]' () +42: UnderlinedText -> UnderlinedTextStart FormattedText UnderlinedTextEnd ( FormattedText Result ) +43: UnderlinedTextStart -> '[u]' ( ) +44: UnderlinedTextEnd -> '[/u]' () +45: Image -> ImageStart ImageURL ImageEnd ( ImageURL Result ) +46: ImageStart -> '[img ' 'alt' '=' QuotedString ']' ( value /> )
+47: ImageStart				-> '[img]'													( <image> )
+48: ImageURL				-> ' Image URL ending with jpg, gif or png'					( TextNode with RHS contents )
+49: ImageEnd				-> '[/img]'													()
+50: URL						-> URLStart Link URLEnd										( <url ...> Link Result </url> )
+51: URLStart				-> '[url ' 'description' '=' QuotedString ']'				( <url description= ) +52: URLStart -> '[url]' ( ) +53: URLEnd -> '[/url]' () +54: Link -> ' URL Starting with http://, https:// or www ' ( TextNode with RHS contents ) +55: EmailAddress -> ' any legitimate emailaddress representation ' ( RHS contents ) +56: OfftopicText -> OfftopicTextStart FormattedText OfftopicTextEnd ( FormattedText Result +57: OfftopicTextStart -> '[offtopic]' ( ) +58: OfftopicTextEnd -> '[/offtopic]' () +59: List -> ListStart ListItems ListEnd ( ListItems Result ) +60: ListStart -> '[list ' 'type' '=' QuotedListType ']' ( ) +61: ListStart -> '[list]' ( ) +62: ListItems -> ListItem ListItems ( ListItem Result Contents of RHS ListItems ) +63: ListItems -> ListItem ( ListItem Result ) +64: ListItem -> '[*]' SpecialText '[/*]' ( SpecialText Result ) +65: ListEnd -> '[/list]' () +66: SizedText -> SizedTextStart FormattedText SizedTextEnd ( FormattedText Result ) +67: SizedTextStart -> '[size ' 'value' '=' SizeNumber ']' ( ) +68: SizedTextEnd -> '[/size]' () +69: ColoredText -> ColoredTextStart FormattedText ColoredTextEnd ( FormattedText Result ) +70: ColoredTextStart -> '[color ' 'value' '=' QuotedString ']' ( ) +71: ColoredTextEnd -> '[/color]' () +72: Smiley -> SmileyLaugh ( RHS Result ) +73: Smiley -> SmileyAngry ( RHS Result ) +74: Smiley -> SmileyRegular ( RHS Result ) +75: Smiley -> SmileyWink ( RHS Result ) +76: Smiley -> SmileyCool ( RHS Result ) +77: Smiley -> SmileyTongue ( RHS Result ) +78: Smiley -> SmileyConfused ( RHS Result ) +79: Smiley -> SmileyShocked ( RHS Result ) +80: Smiley -> SmileyDissapointed ( RHS Result ) +81: Smiley -> SmileySad ( RHS Result ) +82: Smiley -> SmileyEmbarassed ( RHS Result ) +83: SmileyLaugh -> ':D' ( ) +84: SmileyAngry -> ':(' ( ) +85: SmileyRegular -> ':)' ( ) +86: SmileyWink -> ';)' ( ) +87: SmileyCool -> '8)' ( ) +88: SmileyTongue -> ':P' ( ) +89: SmileyConfused -> ':?' ( ) +90: SmileyShocked -> ':o' ( ) +91: SmileyDissapointed -> ':/' ( ) +92: SmileySad -> ';(' ( ) +93: SmileyEmbarassed -> ':!' ( ) + + +Example UBB code +================== + +This is example UBB compatible text +[img alt="picture of me"]http://www.someurl.com/foo.jpg[/img] +[b][color value="FF0000"]RED[/color] Bold[/b] Normal + +In tokens: +Token : Literal matched text +--------------------------------+------------------------------------------------- +UntokenizedLiteralString : This +Whitespace : (space) +UntokenizedLiteralString : is +Whitespace : (space) +UntokenizedLiteralString : example +Whitespace : (space) +UntokenizedLiteralString : UBB +Whitespace : (space) +UntokenizedLiteralString : compatible +Whitespace : (space) +UntokenizedLiteralString : text +CRLF : \n +ImageStartTag : [img +Whitespace : (space) +Alt : Alt +Assignment : = +QuotedString : "ThisIsQuoted" +TagCloseBracket : ] +ImageURL : http://www.mysite.org/foo.jpg +ImageEndTag : [/img] +CRLF : \n +BoldStartTag : [b] +ColorStartTag : [color +Assignment : = +QuotedString : "FF0000" +TagCloseBracket : ] +UntokenizedLiteralString : RED +Whitespace : (space) +ColorEndTag : [/color] +Whitespace : (space) +UntokenizedLiteralString : Bold +BoldEndTag : [/b] +Whitespace : (space) +UntokenizedLiteralString : Normal + + + + + + + + + + + + diff --git a/UBBParser/UBBParser/UBBToken.cs b/UBBParser/UBBParser/UBBToken.cs new file mode 100644 index 0000000..a7a291d --- /dev/null +++ b/UBBParser/UBBParser/UBBToken.cs @@ -0,0 +1,86 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; + +namespace SD.HnD.UBBParser +{ + /// + /// Implements the IToken interface for the UBB parser for HnD + /// + public class UBBToken : IToken + { + #region Class Member Declarations + private UBBTokenDefinition _relatedTokenDefinition; + private string _literalMatchedTokenText; + private int _startIndexInInputStream; + #endregion + + + /// + /// CTor + /// + public UBBToken() + { + } + + + #region Class Property Declarations + /// + /// Gets the token ID. + /// + /// + public int TokenID + { + get { return _relatedTokenDefinition.TokenID; } + } + + /// + /// Gets or sets the literal matched token text. + /// + /// + public string LiteralMatchedTokenText + { + get { return _literalMatchedTokenText; } + set { _literalMatchedTokenText = value; } + } + + /// + /// Gets or sets the related token definition. + /// + /// + public ITokenDefinition RelatedTokenDefinition + { + get { return _relatedTokenDefinition; } + set { _relatedTokenDefinition = (UBBTokenDefinition)value; } + } + + /// + /// Gets or sets the start index in input stream. + /// + /// + public int StartIndexInInputStream + { + get { return _startIndexInInputStream; } + set { _startIndexInInputStream = value; } + } + #endregion + + } +} diff --git a/UBBParser/UBBParser/UBBTokenDefinition.cs b/UBBParser/UBBParser/UBBTokenDefinition.cs new file mode 100644 index 0000000..214f526 --- /dev/null +++ b/UBBParser/UBBParser/UBBTokenDefinition.cs @@ -0,0 +1,86 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2006 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Text.RegularExpressions; + +namespace SD.HnD.UBBParser +{ + /// + /// UBBTokenDefinition. Implements ITokenDefinition + /// + public class UBBTokenDefinition : ITokenDefinition + { + #region Class Member Declarations + private int _tokenID; + private Regex _matchingRegularExpression; + #endregion + + /// + /// CTor + /// + public UBBTokenDefinition() + { + } + + + /// + /// CTor + /// + public UBBTokenDefinition(int tokenID, string matchingRegularExpression, RegexOptions regularExpressionOptions) + { + _tokenID = tokenID; + _matchingRegularExpression = new Regex(matchingRegularExpression, regularExpressionOptions); + } + + + /// + /// Creates a new token object using this definition and prefills it. + /// + /// An TDLToken token + public IToken CreateTokenFromDefinition() + { + UBBToken toReturn = new UBBToken(); + toReturn.RelatedTokenDefinition = this; + return toReturn; + } + + + #region Class Property Definitions + /// + /// gets / sets the tokenid for this tokenobject + /// + public int TokenID + { + get { return _tokenID; } + set { _tokenID = value; } + } + + /// + /// gets/ sets the matching regular expression object + /// + public Regex MatchingRegularExpression + { + get { return _matchingRegularExpression; } + set { _matchingRegularExpression = value; } + } + #endregion + + } +} diff --git a/UBBParser/UBBtoXMLConverter.sln b/UBBParser/UBBtoXMLConverter.sln new file mode 100644 index 0000000..05b091e --- /dev/null +++ b/UBBParser/UBBtoXMLConverter.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UBBParser", "UBBParser\UBBParser.csproj", "{22A260C0-742F-42A7-82AB-DDB792082900}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tester", "ParserTester\Tester.csproj", "{D32F2A6C-D650-40BC-9A74-24190B3D970A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {22A260C0-742F-42A7-82AB-DDB792082900}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22A260C0-742F-42A7-82AB-DDB792082900}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22A260C0-742F-42A7-82AB-DDB792082900}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22A260C0-742F-42A7-82AB-DDB792082900}.Release|Any CPU.Build.0 = Release|Any CPU + {D32F2A6C-D650-40BC-9A74-24190B3D970A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D32F2A6C-D650-40BC-9A74-24190B3D970A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D32F2A6C-D650-40BC-9A74-24190B3D970A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D32F2A6C-D650-40BC-9A74-24190B3D970A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Utility/AssemblyInfo.cs b/Utility/AssemblyInfo.cs new file mode 100644 index 0000000..231870b --- /dev/null +++ b/Utility/AssemblyInfo.cs @@ -0,0 +1,76 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("SD.HnD.Utility")] +[assembly: AssemblyDescription("HnD's Utility Library")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Solutions Design")] +[assembly: AssemblyProduct( "HnD, a .NET 2.0 Forum system using LLBLGen Pro" )] +[assembly: AssemblyCopyright( "(c)2002-2006 Solutions Design" )] +[assembly: AssemblyTrademark( "HnD, LLBLGen and LLBLGen Pro are trademarks of Solutions Design." )] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("2.0.0.0")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/Utility/GeneralUtils.cs b/Utility/GeneralUtils.cs new file mode 100644 index 0000000..11bb8e9 --- /dev/null +++ b/Utility/GeneralUtils.cs @@ -0,0 +1,199 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Text; +using System.Text.RegularExpressions; +using System.Net.Mail; +using System.IO; +using System.Security.Cryptography; +using System.Collections; +using System.Globalization; +using System.Collections.Generic; +using System.Net; + +namespace SD.HnD.Utility +{ + /// + /// General class for general utility routines. + /// + public class GeneralUtils + { + /// + /// Private constant for the maximum length for a generated password. + /// + private static readonly int GeneratedPasswordLength = 10; + + + /// + /// Tries the value to convert to int. If convert fails due to an exception, 0 is returned. + /// + /// To convert. + /// int value which is represented by the string representation toConvert, or 0 if conversion failed + public static int TryConvertToInt(string toConvert) + { + int toReturn = 0; + if(!Int32.TryParse(toConvert, out toReturn)) + { + toReturn = 0; + } + return toReturn; + } + + + /// + /// Tries the value to convert to short. If convert fails due to an exception, 0 is returned. + /// + /// To convert. + /// short value which is represented by the string representation toConvert, or 0 if conversion failed + public static short TryConvertToShort(string toConvert) + { + short toReturn = 0; + if(!Int16.TryParse(toConvert, out toReturn)) + { + toReturn = 0; + } + return toReturn; + } + + + /// + /// Generates a random password string. The password generated contains solely readable + /// characters available on every keyboard. + /// + /// a password string, generated using a randomizer. + public static string GenerateRandomPassword() + { + StringBuilder newPassword = new StringBuilder(GeneratedPasswordLength); + + // create randomizer object + Random rand = new Random(DateTime.Now.Millisecond + DateTime.Now.Second); + + for(int i = 0, randomNr=0;i < GeneratedPasswordLength; i++) + { + bool isValid = false; + while(!isValid) + { + randomNr = rand.Next(33, 126); + isValid = (randomNr > 47 && randomNr < 58) || (randomNr > 64 && randomNr < 91) || + (randomNr > 96 && randomNr < 123); + } + newPassword.Append(Convert.ToChar(randomNr)); + } + return newPassword.ToString(); + } + + + /// + /// Computes the MD5 hash value for the given string and converts the result into a Base64 encoded string. + /// This string is directly comparable with and storable in the User table as a password. + /// + /// String to hash and encode + /// MD5 hashed, Base64 encoded value of the given string + public static string CreateMD5HashedBase64String(string sToHash) + { + // get generic MD5 hasher + MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider(); + return Convert.ToBase64String(md5Hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sToHash))); + } + + + /// + /// Sends the email specified to the addresses specified. + /// + /// Subject. + /// Message. + /// From address. + /// To email addresses. + /// The email data. + /// if set to true, the email will be send asynchronically otherwise synchronically + /// true if email sent, otherwise false + public static bool SendEmail(string subject, string message, string fromAddress, string[] toEmailAddresses, + Dictionary emailData, bool sendAsynchronically) + { + string defaultToMailAddress = string.Empty; + emailData.TryGetValue("defaultToEmailAddress", out defaultToMailAddress); + + MailMessage messageToSend = new MailMessage(fromAddress, defaultToMailAddress); + messageToSend.Subject=subject; + messageToSend.Body = message; + for(int i = 0; i < toEmailAddresses.Length; i++) + { + messageToSend.Bcc.Add(new MailAddress(toEmailAddresses[i])); + } + messageToSend.IsBodyHtml = false; + + // host and smtp credentials are set in .config file + SmtpClient client = new SmtpClient(); + if(sendAsynchronically) + { + // send email asynchronously. + client.SendAsync(messageToSend, null); + } + else + { + client.Send(messageToSend); + } + return true; + } + + + /// + /// Emails the given password to the given emailaddress. No username is specified. + /// + /// The password to email + /// The recipient's emailaddress. + /// The email template. + /// The email data. + /// true if succeeded, false otherwise + public static bool EmailPassword(string password, string emailAddress, string emailTemplate, Dictionary emailData) + { + StringBuilder mailBody = new StringBuilder(emailTemplate); + + string applicationURL = string.Empty; + emailData.TryGetValue("applicationURL", out applicationURL); + + if (!string.IsNullOrEmpty(emailTemplate)) + { + // Use the existing template to format the body + string siteName = string.Empty; + emailData.TryGetValue("siteName", out siteName); + + mailBody.Replace("[URL]", applicationURL); + mailBody.Replace("[SiteName]", siteName); + mailBody.Replace("[Password]", password); + } + + // format the subject + string subject = string.Empty; + emailData.TryGetValue("emailPasswordSubject", out subject); + subject += applicationURL; + + string fromAddress = string.Empty; + emailData.TryGetValue("defaultFromEmailAddress", out fromAddress); + + // send it + // host and smtp credentials are set in .config file + SmtpClient client = new SmtpClient(); + client.Send(fromAddress, emailAddress, subject, mailBody.ToString()); + return true; + } + + } +} diff --git a/Utility/HnDGeneralUtils.cs b/Utility/HnDGeneralUtils.cs new file mode 100644 index 0000000..d1eb6ad --- /dev/null +++ b/Utility/HnDGeneralUtils.cs @@ -0,0 +1,199 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Text; +using System.Text.RegularExpressions; +using System.Net.Mail; +using System.IO; +using System.Security.Cryptography; +using System.Collections; +using System.Globalization; +using System.Collections.Generic; +using System.Net; + +namespace SD.HnD.Utility +{ + /// + /// General class for general utility routines. + /// + public class HnDGeneralUtils + { + /// + /// Private constant for the maximum length for a generated password. + /// + private static readonly int GeneratedPasswordLength = 10; + + + /// + /// Tries the value to convert to int. If convert fails due to an exception, 0 is returned. + /// + /// To convert. + /// int value which is represented by the string representation toConvert, or 0 if conversion failed + public static int TryConvertToInt(string toConvert) + { + int toReturn = 0; + if(!Int32.TryParse(toConvert, out toReturn)) + { + toReturn = 0; + } + return toReturn; + } + + + /// + /// Tries the value to convert to short. If convert fails due to an exception, 0 is returned. + /// + /// To convert. + /// short value which is represented by the string representation toConvert, or 0 if conversion failed + public static short TryConvertToShort(string toConvert) + { + short toReturn = 0; + if(!Int16.TryParse(toConvert, out toReturn)) + { + toReturn = 0; + } + return toReturn; + } + + + /// + /// Generates a random password string. The password generated contains solely readable + /// characters available on every keyboard. + /// + /// a password string, generated using a randomizer. + public static string GenerateRandomPassword() + { + StringBuilder newPassword = new StringBuilder(GeneratedPasswordLength); + + // create randomizer object + Random rand = new Random(DateTime.Now.Millisecond + DateTime.Now.Second); + + for(int i = 0, randomNr=0;i < GeneratedPasswordLength; i++) + { + bool isValid = false; + while(!isValid) + { + randomNr = rand.Next(33, 126); + isValid = (randomNr > 47 && randomNr < 58) || (randomNr > 64 && randomNr < 91) || + (randomNr > 96 && randomNr < 123); + } + newPassword.Append(Convert.ToChar(randomNr)); + } + return newPassword.ToString(); + } + + + /// + /// Computes the MD5 hash value for the given string and converts the result into a Base64 encoded string. + /// This string is directly comparable with and storable in the User table as a password. + /// + /// String to hash and encode + /// MD5 hashed, Base64 encoded value of the given string + public static string CreateMD5HashedBase64String(string sToHash) + { + // get generic MD5 hasher + MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider(); + return Convert.ToBase64String(md5Hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sToHash))); + } + + + /// + /// Sends the email specified to the addresses specified. + /// + /// Subject. + /// Message. + /// From address. + /// To email addresses. + /// The email data. + /// if set to true, the email will be send asynchronically otherwise synchronically + /// true if email sent, otherwise false + public static bool SendEmail(string subject, string message, string fromAddress, string[] toEmailAddresses, + Dictionary emailData, bool sendAsynchronically) + { + string defaultToMailAddress = string.Empty; + emailData.TryGetValue("defaultToEmailAddress", out defaultToMailAddress); + + MailMessage messageToSend = new MailMessage(fromAddress, defaultToMailAddress); + messageToSend.Subject=subject; + messageToSend.Body = message; + for(int i = 0; i < toEmailAddresses.Length; i++) + { + messageToSend.Bcc.Add(new MailAddress(toEmailAddresses[i])); + } + messageToSend.IsBodyHtml = false; + + // host and smtp credentials are set in .config file + SmtpClient client = new SmtpClient(); + if(sendAsynchronically) + { + // send email asynchronously. + client.SendAsync(messageToSend, null); + } + else + { + client.Send(messageToSend); + } + return true; + } + + + /// + /// Emails the given password to the given emailaddress. No username is specified. + /// + /// The password to email + /// The recipient's emailaddress. + /// The email template. + /// The email data. + /// true if succeeded, false otherwise + public static bool EmailPassword(string password, string emailAddress, string emailTemplate, Dictionary emailData) + { + StringBuilder mailBody = new StringBuilder(emailTemplate); + + string applicationURL = string.Empty; + emailData.TryGetValue("applicationURL", out applicationURL); + + if (!string.IsNullOrEmpty(emailTemplate)) + { + // Use the existing template to format the body + string siteName = string.Empty; + emailData.TryGetValue("siteName", out siteName); + + mailBody.Replace("[URL]", applicationURL); + mailBody.Replace("[SiteName]", siteName); + mailBody.Replace("[Password]", password); + } + + // format the subject + string subject = string.Empty; + emailData.TryGetValue("emailPasswordSubject", out subject); + subject += applicationURL; + + string fromAddress = string.Empty; + emailData.TryGetValue("defaultFromEmailAddress", out fromAddress); + + // send it + // host and smtp credentials are set in .config file + SmtpClient client = new SmtpClient(); + client.Send(fromAddress, emailAddress, subject, mailBody.ToString()); + return true; + } + + } +} diff --git a/Utility/LICENSE.txt b/Utility/LICENSE.txt new file mode 100644 index 0000000..6e812ec --- /dev/null +++ b/Utility/LICENSE.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/Utility/SD.HnD.Utility.csproj b/Utility/SD.HnD.Utility.csproj new file mode 100644 index 0000000..278289c --- /dev/null +++ b/Utility/SD.HnD.Utility.csproj @@ -0,0 +1,153 @@ + + + + Local + 8.0.50727 + 2.0 + {AAEB0829-9929-4706-B7FB-F4E8BFCC32C2} + Debug + AnyCPU + + + + + SD.HnD.Utility + + + JScript + Grid + IE50 + false + Library + SD.HnD.Utility + OnBuildSuccess + + + + + + + v3.5 + 2.0 + http://localhost/SD.HnD.Utility/ + true + Web + true + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + true + false + true + + + + bin\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + AllRules.ruleset + + + bin\Release\ + false + 285212672 + false + + + TRACE + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + AllRules.ruleset + + + + False + ..\ParserAssemblies\SD.HnD.UBBParser.dll + + + System + + + System.Data + + + System.Web + + + System.XML + + + + + Code + + + Code + + + Code + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + + + \ No newline at end of file diff --git a/Utility/TextParser.cs b/Utility/TextParser.cs new file mode 100644 index 0000000..8fb161b --- /dev/null +++ b/Utility/TextParser.cs @@ -0,0 +1,178 @@ +/* + This file is part of HnD. + HnD is (c) 2002-2007 Solutions Design. + http://www.llblgen.com + http://www.sd.nl + + HnD is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as published by + the Free Software Foundation. + + HnD 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 HnD, please see the LICENSE.txt file; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +using System; +using System.Collections; +using System.Xml; +using System.Xml.Xsl; +using System.Text; + +using SD.HnD.UBBParser; +using System.IO; + +namespace SD.HnD.Utility +{ + /// + /// Structure used to store data related to the parser in the application object. + /// + public struct ParserData + { + public XslCompiledTransform MessageStyle; + public XslCompiledTransform SignatureStyle; + } + + /// + /// General Text Code parser. This class converts passed in texts with UBB/other codes to texts with HTML code. + /// It uses a UBB Special parser build with the parser framework. It assumes the parser engine tables are + /// already serialized into objects located in the Application Object. + /// + public static class TextParser + { + /// + /// Used by the re-parser to parse a message to xml. + /// + /// the text of the message in UBB format + /// if true, HTML is also re-generated + /// The parser data. + /// the XML parse result for the ubbstring + /// if reGenerateHTML is set to true, this contains the HTML output for the message + public static void ReParseMessage(string messageText, bool reGenerateHTML, ParserData parserData, out string messageTextXML, out string messageTextHTML) + { + bool errorsOccured = false; + string parseLog = string.Empty; + messageTextXML = string.Empty; + messageTextHTML = TransformUBBStringToHTML(messageText, true, reGenerateHTML, parserData, out parseLog, out errorsOccured, out messageTextXML); + } + + + /// + /// Transforms the given message with all its forumtags to HTML using the specified XSL template and returns that HTML string. The + /// XSL template is cached inside the Application object, so the name specified is the name of the Application object's property holding the + /// XSL template. + /// + /// Text to transform + /// The parser data. + /// Output parameter, contains the parserlog of the parse process + /// Output parameter, contains true if the parser found one or more errors in sUBBString, false otherwise + /// The parse result in XML format (string) + /// ubbString in HTML format + public static string TransformUBBMessageStringToHTML(string ubbString, ParserData parserData, out string parserLog, out bool errorsOccured, out string messageTextXML) + { + return TransformUBBStringToHTML(ubbString, true, true, parserData, out parserLog, out errorsOccured, out messageTextXML); + } + + + /// + /// Will transform a given signature to HTML using the UBB parser. Only several tags are supported. These tags are filtered by the + /// special signature xsl sheet. The input is already limited to the maximum signature size. + /// + /// Signature to transform to HTML + /// The parser data. + /// Signature in HTML format. + public static string TransformSignatureUBBStringToHTML(string signature, ParserData parserData) + { + string parserLog, messageTextXML; + bool errorsOccured; + return TransformUBBStringToHTML(signature, false, true, parserData, out parserLog, out errorsOccured, out messageTextXML); + } + + + /// + /// Transforms the given text with all its forumtags to HTML using the specified XSL template and returns that HTML string. The + /// XSL template is cached inside the Application object, so the name specified is the name of the Application object's property holding the + /// XSL template. + /// + /// Text to transform + /// Pass true to use the message style and false to use the signature style + /// set to false when the parser is just used to create a wordlist. + /// The parser data. + /// Output parameter, contains the parserlog of the parse process + /// Output parameter, contains true if the parser found one or more errors in sUBBString, false otherwise + /// THe parser result as XML string + /// ubbString in HTML format + private static string TransformUBBStringToHTML(string ubbString, bool isMessageTransform, bool performHtmlConversion, ParserData parserData, out string parserLog, + out bool errorsOccured, out string messageTextXML) + { + parserLog=string.Empty; + errorsOccured=false; + + messageTextXML = string.Empty; + + if(ubbString==null) + { + return ""; + } + + // parse it + try + { + XmlDocument emitterResult = Converter.ConvertToXml(ubbString); + messageTextXML = emitterResult.OuterXml; + errorsOccured = false; + + if(performHtmlConversion) + { + // Transform Emitter result into HTML using the xsl specified. + XslCompiledTransform xslTransformer = parserData.MessageStyle; + if (!isMessageTransform) + { + xslTransformer = parserData.SignatureStyle; + } + + // in .NET 2.0, the XmlCompiledTransform doesn't have a way to transform to a reader or string. So we'll transform to a stream + // which we'll use to read back into a stringbuilder which is faster with replacing tab characters to 4 spaces. + MemoryStream outputStream = new MemoryStream(); + xslTransformer.Transform(emitterResult, null, outputStream); + outputStream.Seek(0, SeekOrigin.Begin); + + StreamReader reader = new StreamReader(outputStream); + StringBuilder htmlOutput = new StringBuilder(reader.ReadToEnd()); + reader.Close(); // closes underlying stream as well. + + // replace any tab chars with 4 HTML spaces + htmlOutput.Replace("\t", "    "); + return htmlOutput.ToString(); + } + else + { + return string.Empty; + } + } + catch + { + // exception occured. Don't proceed with passed in text, simply return empty string. + errorsOccured=true; + return string.Empty; + } + } + + + /// + /// Transforms the passed in string into a string with quote tags, which is used to be included + /// into a message as a 'quoted' part of a previous message. + /// + /// String to quote + /// Nickname of poster who posted the string to Quote + /// string modified so it is quoted for the editor + public static string MakeStringQuoted(string toQuote, string nickName) + { + return string.Format("[quote nick=\"{0}\"]{1}[/quote]\n", nickName, toQuote); + } + } +}