private PageBE Pages_PopulatePage(IDataReader dr) { PageBE p = new PageBE(); p._Comment = dr.Read <byte[]>("page_comment"); p._DisplayName = dr.Read <string>("page_display_name"); p._Namespace = dr.Read <ushort>("page_namespace"); p._TimeStamp = dr.Read <string>("page_timestamp"); p._Title = dr.Read <string>("page_title"); p._Touched = dr.Read <string>("page_touched"); p.ContentType = dr.Read <string>("page_content_type"); p.ID = dr.Read <ulong>("page_id"); p.IsNew = dr.Read <bool>("page_is_new"); p.IsHidden = dr.Read <bool>("page_is_hidden"); p.IsRedirect = dr.Read <bool>("page_is_redirect"); p.Language = dr.Read <string>("page_language"); p.Meta = dr.Read <string>("page_meta"); p.MinorEdit = dr.Read <bool>("page_minor_edit"); p.ParentID = dr.Read <ulong>("page_parent"); p.RestrictionID = dr.Read <uint>("page_restriction_id"); p.Revision = dr.Read <uint>("page_revision"); p.TextLength = dr.Read <int>("page_text_length"); p.TIP = dr.Read <string>("page_tip"); p.UseCache = dr.Read <bool>("page_usecache"); p.UserID = dr.Read <uint>("page_user_id"); p.Etag = dr.Read <string>("page_etag"); return(p); }
public Dictionary <ulong, IList <PageBE> > Pages_GetRedirects(IList <ulong> pageIds) { Dictionary <ulong, IList <PageBE> > ret = new Dictionary <ulong, IList <PageBE> >(); if (pageIds == null || pageIds.Count == 0) { return(ret); } string pageIdsText = pageIds.ToCommaDelimitedString(); string query = string.Format(@" /* PageDA::Pages_GetRedirects */ SELECT l_to, {0} FROM pages p JOIN links ON p.page_id = l_from WHERE p.page_is_redirect=1 AND l_to IN({1}); ", PAGEFIELDS, pageIdsText); Catalog.NewQuery(query) .Execute(delegate(IDataReader dr) { while (dr.Read()) { PageBE p = Pages_PopulatePage(dr); ulong to = dr.Read <ulong>("l_to"); IList <PageBE> redirectsForId = null; if (!ret.TryGetValue(to, out redirectsForId)) { ret[to] = redirectsForId = new List <PageBE>(); } redirectsForId.Add(p); } }); return(ret); }
public void Pages_Update(PageBE page) { // Update page text only if it has been set string updatePageText = String.Empty; if (page.IsTextPopulated) { updatePageText = ", page_text = ?PAGETEXT"; } string query = String.Format(@" /* Pages_Update */ update pages SET page_namespace = ?NAMESPACE, page_title = ?TITLE, page_comment = ?PAGECOMMENT, page_user_id = ?USERID, page_timestamp = ?PAGETIMESTAMP, page_is_redirect = ?ISREDIRECT, page_minor_edit = ?MINOREDIT, page_is_new = ?ISNEW, page_touched = ?TOUCHED, page_usecache = ?USECACHE, page_tip = ?TIP, page_parent = ?PARENT, page_restriction_id = ?RESTRICTIONID, page_content_type = ?CONTENTTYPE, page_language = ?LANGUAGE, page_display_name = ?DISPLAYNAME, page_etag = ?ETAG, page_revision = ?REVISION {0} where page_id = ?PAGEID ", updatePageText); DataCommand cmd = Catalog.NewQuery(query) .With("PAGEID", page.ID) .With("NAMESPACE", (int)page.Title.Namespace) .With("TITLE", page.Title.AsUnprefixedDbPath()) .With("PAGECOMMENT", page.Comment) .With("USERID", page.UserID) .With("PAGETIMESTAMP", page._TimeStamp) .With("ISREDIRECT", page.IsRedirect) .With("MINOREDIT", page.MinorEdit) .With("ISNEW", page.IsNew) .With("TOUCHED", page._Touched) .With("USECACHE", page.UseCache) .With("TIP", page.TIP) .With("PARENT", page.ParentID) .With("RESTRICTIONID", page.RestrictionID) .With("CONTENTTYPE", page.ContentType) .With("LANGUAGE", page.Language) .With("DISPLAYNAME", page.Title.DisplayName) .With("ETAG", page.Etag) .With("REVISION", page.Revision); if (page.IsTextPopulated) { cmd.With("PAGETEXT", page.GetText(this.Head)); } cmd.Execute(); }
private static PageBE PopulateOld(IDataRecord dr) { PageBE old = new PageBE(); old.ID = DbUtils.Convert.To <ulong>(dr["rev_id"]).Value; old._Namespace = DbUtils.Convert.To <ushort>(dr["page_namespace"]).Value; old._Title = GetUTF8String(dr, "page_title"); old.SetText(GetUTF8String(dr, "old_text")); old.Comment = GetUTF8String(dr, "rev_comment"); if (MediaWikiConverterContext.Current.Merge) { old.UserID = MediaWikiConverterContext.Current.MergeUserId; } else { old.UserID = DbUtils.Convert.To <uint>(dr["rev_user"]).Value; } old.TimeStamp = DbUtils.ToDateTime(GetUTF8String(dr, "rev_timestamp")); old.MinorEdit = DbUtils.Convert.To <bool>(dr["rev_minor_edit"]).Value; old.ContentType = DekiMimeType.MEDIAWIKI_TEXT; if (MediaWikiConverterContext.Current.AttributeViaPageRevComment) { //Add the original revision username to the comment string username = GetUTF8String(dr, "rev_user_text"); if (!string.IsNullOrEmpty(username)) { old.Comment = string.Format(MediaWikiConverterContext.Current.AttributeViaPageRevCommentPattern, old.Comment, username); } } return(old); }
public virtual ResourceBE Delete(ResourceBE resource, PageBE parentPage, uint changeSetId) { //Build the new revision ResourceBE res = BuildRevForRemove(resource, DateTime.UtcNow, changeSetId); //Update db res = SaveResource(res); //Update indexes and parent page's timestamp //TODO MaxM: Changesink needs to accept a resource if (res.ResourceType == ResourceBE.Type.FILE) { DekiContext.Current.Instance.EventSink.AttachmentDelete(DekiContext.Current.Now, res, DekiContext.Current.User); // Recent changes RecentChangeBL.AddFileRecentChange(DekiContext.Current.Now, parentPage, DekiContext.Current.User, DekiResources.FILE_REMOVED(res.Name), changeSetId); } if (parentPage != null) { PageBL.Touch(parentPage, DateTime.UtcNow); } return(res); }
public static XDoc BuildXmlSiteMap(PageBE rootPage, string language) { Dictionary <ulong, PageBE> pagesById = null; rootPage = PageBL.PopulateDescendants(rootPage, null, out pagesById, ConfigBL.GetInstanceSettingsValueAs <int>(ConfigBL.MAX_SITEMAP_SIZE_KEY, ConfigBL.MAX_SITEMAP_SIZE)); PageBE[] allowedPages = PermissionsBL.FilterDisallowed(DekiContext.Current.User, new List <PageBE>(pagesById.Values).ToArray(), false, new Permissions[] { Permissions.BROWSE }); Dictionary <ulong, PageBE> allowedPagesById = allowedPages.AsHash(e => e.ID); Dictionary <ulong, PageBE> addedPagesById = null; if (!string.IsNullOrEmpty(language)) { List <ulong> pagesToRemove = new List <ulong>(); foreach (KeyValuePair <ulong, PageBE> page in allowedPagesById) { if (!string.IsNullOrEmpty(page.Value.Language) && !StringUtil.EqualsInvariantIgnoreCase(page.Value.Language, language)) { pagesToRemove.Add(page.Key); } } foreach (ulong pageId in pagesToRemove) { allowedPagesById.Remove(pageId); } } PageBL.AddParentsOfAllowedChildren(rootPage, allowedPagesById, addedPagesById); return(BuildXmlSiteMap(rootPage, new XDoc("pages"), allowedPagesById)); }
public static Dictionary <Site, List <PageBE> > GetPagesBySite() { Dictionary <Site, List <PageBE> > pagesBySite = new Dictionary <Site, List <PageBE> >(); foreach (Site site in MediaWikiConverterContext.Current.MWSites) { List <PageBE> pages = new List <PageBE>(); pagesBySite[site] = pages; MediaWikiConverterContext.Current.MWCatalog.NewQuery(String.Format( @"SELECT page_id, page_namespace, page_title, page_restrictions, page_is_redirect, page_is_new, page_touched, rev_user, rev_timestamp, rev_minor_edit, rev_comment, old_text, rev_user_text FROM {0}page JOIN {0}revision on {0}revision.rev_id = {0}page.page_latest JOIN {0}text on {0}revision.rev_text_id = {0}text.old_id", site.DbPrefix)).Execute(delegate(IDataReader dr) { while (dr.Read()) { PageBE page = PopulatePage(dr); if (IsSupportedNamespace(page.Title)) { page.Language = site.Language; pages.Add(page); } } }); } return(pagesBySite); }
private void NotifyPropertyParent(DateTime eventTime, ResourceBE prop, UserBE user, ResourceBE.ParentType parentType, string action) { if (parentType == ResourceBE.ParentType.PAGE && prop.ParentPageId != null) { PageBE parentPage = PageBL.GetPageById(prop.ParentPageId.Value); if (parentPage != null) { PageDependentChanged(eventTime, parentPage, user, PROPERTY, action); } } else if (parentType == ResourceBE.ParentType.USER) { // Owner of property may not be same as requesting user. // The dependentschanged event is triggered on the property owner. if (prop.ParentUserId != null) { // Optimization to avoid a db call when operating on your own user property. if (user.ID != prop.ParentUserId.Value) { user = UserBL.GetUserById(prop.ParentUserId.Value); if (user == null) { _log.WarnFormat("Could not find owner user (id: {0}) of user property (key: {1})", prop.ParentUserId.Value, prop.Name); return; } } } UserDependentChanged(eventTime, user, PROPERTY, action); } //TODO (maxm): trigger file property changes }
public IList <NavBE> Nav_GetChildren(PageBE page) { string query = @" /* Nav_GetChildren */ SELECT page_id, page_namespace, page_title, page_display_name, pages.page_parent as page_parent, restriction_perm_flags, ( SELECT count(C.page_id) FROM pages C WHERE C.page_parent = pages.page_id AND C.page_id != ?HOMEPAGEID AND C.page_parent != ?HOMEPAGEID AND C.page_namespace = ?PAGENS AND C.page_is_redirect = 0 GROUP BY C.page_parent ) AS page_children FROM pages LEFT JOIN restrictions ON page_restriction_id = restriction_id WHERE pages.page_is_redirect = 0 AND ( ( ?HOMEPAGEID != ?PAGEID AND pages.page_parent = ?PAGEID AND pages.page_namespace = ?PAGENS ) OR ( ?HOMEPAGEID = ?PAGEID AND pages.page_parent = 0 AND pages.page_id != ?HOMEPAGEID AND pages.page_namespace = ?PAGENS ) ) "; DataCommand cmd = Catalog.NewQuery(query) .With("HOMEPAGEID", Head.Pages_HomePageId) .With("PAGEID", page.ID) .With("PAGENS", (int)page.Title.Namespace); return(Nav_GetInternal(cmd)); }
private void CommentChanged(DateTime eventTime, CommentBE comment, PageBE parent, UserBE user, params string[] channelPath) { try { XUri channel = _channel.At(COMMENTS).At(channelPath); XUri resource = CommentBL.GetUri(comment).WithHost(_wikiid); string[] origin = new string[] { CommentBL.GetUri(comment).AsServerUri().ToString() }; string path = parent.Title.AsUiUriPath() + "#comment" + comment.Number; XDoc doc = new XDoc("deki-event") //userid is deprecated and user/id should be used instead .Elem("userid", comment.PosterUserId) .Elem("pageid", comment.PageId) .Elem("uri.page", PageBL.GetUriCanonical(parent).AsServerUri().ToString()) .Start("user") .Attr("id", user.ID) .Attr("anonymous", UserBL.IsAnonymous(user)) .Elem("uri", UserBL.GetUri(user)) .End() .Elem("channel", channel) .Elem("uri", CommentBL.GetUri(comment).AsServerUri().ToString()) .Elem("path", path) .Start("content").Attr("uri", CommentBL.GetUri(comment).AsServerUri().At("content").ToString()).End(); if (comment.Content.Length < 255) { doc["content"].Attr("type", comment.ContentMimeType).Value(comment.Content); } Queue(eventTime, channel, resource, origin, doc); } catch (Exception e) { _log.WarnMethodCall("CommentChanged", "event couldn't be created"); } }
public void PageMove(DateTime eventTime, PageBE oldPage, PageBE newPage, UserBE user) { try { XUri channel = _channel.At(PAGES, MOVE); XUri resource = PageBL.GetUriCanonical(newPage).WithHost(_wikiid); var origin = new[] { PageBL.GetUriCanonical(newPage).AsServerUri().ToString(), XUri.Localhost + "/" + oldPage.Title.AsUiUriPath(), XUri.Localhost + "/" + newPage.Title.AsUiUriPath(), }; Queue(eventTime, channel, resource, origin, new XDoc("deki-event") .Elem("channel", channel) .Elem("uri", PageBL.GetUriCanonical(newPage).AsServerUri().ToString()) .Elem("pageid", newPage.ID) .Start("user") .Attr("id", user.ID) .Attr("anonymous", UserBL.IsAnonymous(user)) .Elem("uri", UserBL.GetUri(user)) .End() .Start("content.uri") .Attr("type", "application/xml") .Value(PageBL.GetUriContentsCanonical(newPage).AsServerUri().With("format", "xhtml").ToString()) .End() .Elem("revision.uri", PageBL.GetUriRevisionCanonical(newPage).AsServerUri().ToString()) .Elem("tags.uri", PageBL.GetUriCanonical(newPage).At("tags").AsServerUri().ToString()) .Elem("comments.uri", PageBL.GetUriCanonical(newPage).At("comments").AsServerUri().ToString()) .Elem("path", newPage.Title.AsUiUriPath()) .Elem("previous-path", oldPage.Title.AsUiUriPath())); } catch (Exception e) { _log.WarnExceptionMethodCall(e, "PageMove", "event couldn't be created"); } }
private static void AddCommentRecentChange(DateTime timestamp, PageBE page, UserBE user, DekiResource summary, CommentBE comment, RC rcType) { var resources = DekiContext.Current.Resources; //TODO MaxM: Consider truncating summary DbUtils.CurrentSession.RecentChanges_Insert(timestamp, page, user, resources.Localize(summary), 0, rcType, 0, string.Empty, false, 0); }
public override DekiScriptLiteral ResolveMissingName(string name) { var result = base.ResolveMissingName(name); if (result != null) { return(result); } // check if name refers to a template name Title title = Title.FromUriPath(name); // If the page title is prefixed with :, do not assume the template namespace if (title.Path.StartsWith(":")) { title.Path = title.Path.Substring(1); } else if (title.IsMain) { title.Namespace = NS.TEMPLATE; } PageBE page = PageBL.GetPageByTitle(title); if ((page == null) || (page.ID == 0)) { return(null); } return(DekiScriptExpression.Constant(DekiContext.Current.Deki.Self.At("template"), new DekiScriptList().Add(DekiScriptExpression.Constant(title.AsPrefixedDbPath())))); }
internal static Title GetRelToTitleFromUrl(DreamContext context) { Title relToTitle = null; uint rootId = context.GetParam <uint>("relto", 0); if (0 == rootId) { string path = context.GetParam("reltopath", null); if (null != path) { relToTitle = Title.FromPrefixedDbPath(path, null); } } else { PageBE rootPage = PageBL.GetPageById(rootId); if ((null == rootPage) || (0 == rootPage.ID)) { throw new PageIdInvalidArgumentException(); } else { relToTitle = rootPage.Title; } } if ((null != relToTitle) && relToTitle.IsTalk) { throw new PageReltoTalkInvalidOperationException(); } return(relToTitle); }
public Yield PostArchiveFilesRestore(DreamContext context, DreamMessage request, Result <DreamMessage> response) { PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN); // parameter parsing PageBE destPage = null; string to = context.GetParam("to", string.Empty); if (to != string.Empty) { destPage = PageBL_GetPageFromPathSegment(false, to); } PageBE parentPage; ResourceBE removedFile = GetAttachment(context, request, Permissions.NONE, true, true, out parentPage); if (!removedFile.ResourceIsDeleted) { throw new AttachmentArchiveFileNotDeletedNotFoundException(); } //Optionally move the restored file to the given page if (null == destPage) { destPage = parentPage; } AttachmentBL.Instance.RestoreAttachment(removedFile, destPage, DateTime.UtcNow, 0); response.Return(DreamMessage.Ok()); yield break; }
//--- Class Methods --- public XDoc RecentChanges_GetPageRecentChanges(PageBE page, DateTime since, bool recurse, bool createOnly, uint?limit) { string query = @"/* RecentChanges_GetPageRecentChanges */ SELECT rc_id, rc_comment, rc_cur_id, rc_last_oldid, rc_this_oldid, rc_namespace, rc_timestamp, rc_title, rc_type, rc_moved_to_ns, rc_moved_to_title, user_name AS rc_user_name, user_real_name as rc_full_name, (page_id IS NOT NULL) AS rc_page_exists, IF(page_id IS NULL, 0, page_revision) AS rc_revision, cmnt_id, cmnt_number, cmnt_content, cmnt_content_mimetype, (cmnt_delete_date IS NOT NULL) as cmnt_deleted, old_is_hidden FROM recentchanges LEFT JOIN old ON rc_this_oldid=old_id LEFT JOIN users ON rc_user=user_id LEFT JOIN comments ON ((rc_type=40 AND cmnt_page_id=rc_cur_id AND rc_user=cmnt_poster_user_id AND STR_TO_DATE(rc_timestamp,'%Y%m%e%H%i%s')=cmnt_create_date) OR (rc_type=41 AND cmnt_page_id=rc_cur_id AND rc_user=cmnt_last_edit_user_id AND STR_TO_DATE(rc_timestamp,'%Y%m%e%H%i%s')=cmnt_last_edit) OR (rc_type=42 AND cmnt_page_id=rc_cur_id AND rc_user=cmnt_deleter_user_id AND STR_TO_DATE(rc_timestamp,'%Y%m%e%H%i%s')=cmnt_delete_date)) JOIN ( ( SELECT page_id, page_namespace, page_title, page_revision FROM pages WHERE page_id = {0} ) UNION ( SELECT page_id, page_namespace, page_title, page_revision FROM pages where ({4}) AND (page_is_redirect=0 OR page_is_redirect IS NULL) ) )p ON rc_cur_id = p.page_id {1} {2} ORDER BY rc_timestamp DESC, rc_id DESC LIMIT {3}"; query = string.Format(query, page.ID, Nav_GetTimestampQuery(since), Nav_GetChangeTypeLimitQuery(createOnly), limit ?? UInt32.MaxValue, recurse ? string.Format("(page_title like '{1}%') AND (page_namespace={0} AND (('{1}' = '' AND page_title != '') OR (LEFT(page_title, CHAR_LENGTH('{1}') + 1) = CONCAT('{1}', '/') AND SUBSTRING(page_title, CHAR_LENGTH('{1}') + 2, 1) != '/')))", (int)page.Title.Namespace, DataCommand.MakeSqlSafe(page.Title.AsUnprefixedDbPath())) : string.Format("page_id={0}", page.ID)); return(Catalog.NewQuery(query).ReadAsXDoc("table", "change")); }
protected ResourceBE BuildRevForRestore(ResourceBE currentResource, PageBE targetPage, string resourceName, uint changeSetId) { ResourceBE newRev = _resourceBL.BuildRevForRestore(currentResource, targetPage, resourceName, changeSetId); newRev.MetaXml.FileId = currentResource.MetaXml.FileId; return(newRev); }
private void PropertyExport(PageBE page, ResourceBE file, ResourceBE property) { // Export the property XUri propertyUri = null; string filename = null; if (null != file) { propertyUri = property.PropertyContentUri(AttachmentBL.Instance.GetUri(file)); filename = file.Name; } else { propertyUri = property.PropertyContentUri(PageBL.GetUriCanonical(page)); } if (!_uris.ContainsKey(propertyUri)) { _uris.Add(propertyUri, null); XDoc manifestDoc = new XDoc("property").Elem("name", property.Name) .Elem("filename", filename) .Elem("path", page.Title.AsRelativePath(_relToTitle)) .Start("contents").Attr("type", property.MimeType.ToString()).End(); Add(propertyUri, manifestDoc); } }
//--- Class Methods --- public XDoc RecentChanges_GetPageRecentChanges(PageBE page, DateTime since, bool recurse, bool createOnly, uint? limit) { string query = @"/* RecentChanges_GetPageRecentChanges */ SELECT rc_id, rc_comment, rc_cur_id, rc_last_oldid, rc_this_oldid, rc_namespace, rc_timestamp, rc_title, rc_type, rc_moved_to_ns, rc_moved_to_title, user_name AS rc_user_name, user_real_name as rc_full_name, (page_id IS NOT NULL) AS rc_page_exists, IF(page_id IS NULL, 0, page_revision) AS rc_revision, cmnt_id, cmnt_number, cmnt_content, cmnt_content_mimetype, (cmnt_delete_date IS NOT NULL) as cmnt_deleted, old_is_hidden FROM recentchanges LEFT JOIN old ON rc_this_oldid=old_id LEFT JOIN users ON rc_user=user_id LEFT JOIN comments ON ((rc_type=40 AND cmnt_page_id=rc_cur_id AND rc_user=cmnt_poster_user_id AND STR_TO_DATE(rc_timestamp,'%Y%m%e%H%i%s')=cmnt_create_date) OR (rc_type=41 AND cmnt_page_id=rc_cur_id AND rc_user=cmnt_last_edit_user_id AND STR_TO_DATE(rc_timestamp,'%Y%m%e%H%i%s')=cmnt_last_edit) OR (rc_type=42 AND cmnt_page_id=rc_cur_id AND rc_user=cmnt_deleter_user_id AND STR_TO_DATE(rc_timestamp,'%Y%m%e%H%i%s')=cmnt_delete_date)) JOIN ( ( SELECT page_id, page_namespace, page_title, page_revision FROM pages WHERE page_id = {0} ) UNION ( SELECT page_id, page_namespace, page_title, page_revision FROM pages where ({4}) AND (page_is_redirect=0 OR page_is_redirect IS NULL) ) )p ON rc_cur_id = p.page_id {1} {2} ORDER BY rc_timestamp DESC, rc_id DESC LIMIT {3}"; query = string.Format(query, page.ID, Nav_GetTimestampQuery(since), Nav_GetChangeTypeLimitQuery(createOnly), limit ?? UInt32.MaxValue, recurse ? string.Format("(page_title like '{1}%') AND (page_namespace={0} AND (('{1}' = '' AND page_title != '') OR (LEFT(page_title, CHAR_LENGTH('{1}') + 1) = CONCAT('{1}', '/') AND SUBSTRING(page_title, CHAR_LENGTH('{1}') + 2, 1) != '/')))", (int)page.Title.Namespace, DataCommand.MakeSqlSafe(page.Title.AsUnprefixedDbPath())) : string.Format("page_id={0}", page.ID)); return Catalog.NewQuery(query).ReadAsXDoc("table", "change"); }
public Yield PostFileMove(DreamContext context, DreamMessage request, Result <DreamMessage> response) { PageBE sourcePage = null; PageBE destPage = null; ResourceBE fileToMove = GetAttachmentFromUrl(context, true, out sourcePage, false, false); // parameter parsing string name = context.GetParam("name", null); string to = context.GetParam("to", null); if (string.IsNullOrEmpty(name) && string.IsNullOrEmpty(to)) { throw new AttachmentMoveInvalidArgumentException(); } if (name == null) { name = fileToMove.Name; } destPage = to != null?PageBL_GetPageFromPathSegment(true, to) : sourcePage; //Check if we're actually doing anything if (sourcePage.ID == destPage.ID && fileToMove.Name.EqualsInvariant(name)) { throw new AttachmentNotChangedInvalidOperationException(fileToMove.Name, destPage.Title.AsUserFriendlyName()); } //Ensure write access to source and destination pages. IList <PageBE> pList = PermissionsBL.FilterDisallowed(DekiContext.Current.User, new PageBE[] { sourcePage, destPage }, true, Permissions.UPDATE); // perform the move ResourceBE ret = AttachmentBL.Instance.MoveAttachment(fileToMove, sourcePage, destPage, name, true); response.Return(DreamMessage.Ok(AttachmentBL.Instance.GetFileXml(ret, true, null, false))); yield break; }
public Yield GetFileRevisions(DreamContext context, DreamMessage request, Result <DreamMessage> response) { CheckResponseCache(context, false); //Default change filter is CONTENT changes to preserve backwards compat string changeFilterStr = context.GetParam("changefilter", AttachmentBL.DEFAULT_REVISION_FILTER.ToString()); ResourceBE.ChangeOperations changeFilter = ResourceBE.ChangeOperations.UNDEFINED; if (!string.IsNullOrEmpty(changeFilterStr)) { if (StringUtil.EqualsInvariantIgnoreCase("all", changeFilterStr)) { changeFilter = ResourceBE.ChangeOperations.UNDEFINED; } else if (!SysUtil.TryParseEnum(changeFilterStr, out changeFilter)) { throw new DreamBadRequestException("changefilter value is invalid. Possible values are ALL, " + string.Join(",", Enum.GetNames(typeof(ResourceBE.ChangeOperations)))); } } PageBE parentPage = null; ResourceBE fileRevision = GetAttachment(context, request, Permissions.READ, false, false, out parentPage); XUri listUri = AttachmentBL.Instance.GetUri(fileRevision).At("revisions").With("changefilter", changeFilterStr.ToLowerInvariant()); XDoc ret = AttachmentBL.Instance.GetFileRevisionsXml(fileRevision, changeFilter, listUri, fileRevision.Revision); response.Return(DreamMessage.Ok(ret)); yield break; }
public Yield PostPageRating(DreamContext context, DreamMessage request, Result <DreamMessage> response) { UserBE user = DekiContext.Current.User; if (UserBL.IsAnonymous(user)) { throw new RatingForAnonymousDeniedException(AUTHREALM, string.Empty); } PageBE page = PageBL_AuthorizePage(context, user, Permissions.READ, false); string scoreStr = context.GetParam("score"); float? score = null; if (!string.IsNullOrEmpty(scoreStr)) { float tempScore; if (!float.TryParse(scoreStr, out tempScore)) { throw new RatingInvalidArgumentException(); } score = tempScore; } RatingBL.SetRating(page, user, score); XDoc ret = RatingBL.GetRatingXml(page, user); response.Return(DreamMessage.Ok(ret)); yield break; }
public static Dictionary <Site, List <PageBE> > GetRevisionsBySite() { Dictionary <Site, List <PageBE> > revisionsBySite = new Dictionary <Site, List <PageBE> >(); foreach (Site site in MediaWikiConverterContext.Current.MWSites) { List <PageBE> revisions = new List <PageBE>(); revisionsBySite[site] = revisions; MediaWikiConverterContext.Current.MWCatalog.NewQuery(String.Format( @"SELECT rev_id, page_namespace, page_title, rev_timestamp FROM {0}revision JOIN {0}page on rev_page = page_id JOIN {0}text on rev_text_id = old_id WHERE page_latest!=rev_id", site.DbPrefix)).Execute(delegate(IDataReader dr) { while (dr.Read()) { PageBE revision = PopulatePartialOld(dr); if (IsSupportedNamespace(revision.Title)) { revision.Language = site.Language; revisions.Add(revision); } } }); } return(revisionsBySite); }
public void RecentChanges_Insert(DateTime timestamp, PageBE page, UserBE user, string comment, ulong lastoldid, RC type, uint movedToNS, string movedToTitle, bool isMinorChange, uint transactionId) { string dbtimestamp = DbUtils.ToString(timestamp); string pageTitle = String.Empty; NS pageNamespace = NS.MAIN; ulong pageID = 0; uint userID = 0; if (page != null) { pageTitle = page.Title.AsUnprefixedDbPath(); pageNamespace = page.Title.Namespace; pageID = page.ID; } if (user != null) { userID = user.ID; } string q = "/* RecentChanges_Insert */"; if (lastoldid > 0) { q += @" UPDATE recentchanges SET rc_this_oldid = ?LASTOLDID WHERE rc_namespace = ?NS AND rc_title = ?TITLE AND rc_this_oldid=0;"; } q += @" INSERT INTO recentchanges (rc_timestamp, rc_cur_time, rc_user, rc_namespace, rc_title, rc_comment, rc_cur_id, rc_this_oldid, rc_last_oldid, rc_type, rc_moved_to_ns, rc_moved_to_title, rc_minor, rc_transaction_id) VALUES (?TS, ?TS, ?USER, ?NS, ?TITLE, ?COMMENT, ?CURID, 0, ?LASTOLDID, ?TYPE, ?MOVEDTONS, ?MOVEDTOTITLE, ?MINOR, ?TRANID); "; if (!string.IsNullOrEmpty(comment) && comment.Length > MAXCOMMENTLENGTH) { string segment1 = comment.Substring(0, MAXCOMMENTLENGTH / 2); string segment2 = comment.Substring(comment.Length - MAXCOMMENTLENGTH / 2 + 3); comment = string.Format("{0}...{1}", segment1, segment2); } Catalog.NewQuery(q) .With("TS", dbtimestamp) .With("USER", userID) .With("NS", pageNamespace) .With("TITLE", pageTitle) .With("COMMENT", comment) .With("CURID", pageID) .With("LASTOLDID", lastoldid) .With("TYPE", (uint)type) .With("MOVEDTONS", movedToNS) .With("MOVEDTOTITLE", movedToTitle) .With("MINOR", isMinorChange ? 1 : 0) .With("TRANID", transactionId) .Execute(); }
//--- Class Methods --- public static IList <NavBE> QueryNavTreeData(PageBE page, CultureInfo culture, bool includeAllChildren) { IList <NavBE> navPages = DbUtils.CurrentSession.Nav_GetTree(page, includeAllChildren); navPages = FilterDisallowedNavRecords(navPages, page); navPages = SortNavRecords(navPages, culture); return(navPages); }
public static IList <NavBE> QueryNavSiblingsData(PageBE page, CultureInfo culture) { IList <NavBE> navPages = DbUtils.CurrentSession.Nav_GetSiblings(page); navPages = FilterDisallowedNavRecords(navPages); navPages = SortNavRecords(navPages, culture); return(navPages); }
public Yield GetNavigationSiblings(DreamContext context, DreamMessage request, Result <DreamMessage> response) { CheckResponseCache(context, false); PageBE page = PageBL_GetPageFromUrl(context, false); if (page.Title.IsTalk) { page = PageBL.GetPageByTitle(page.Title.AsFront()); } // build response IList <NavBE> list = NavBL.QueryNavSiblingsData(page, context.Culture); if (ShowDebug(context)) { response.Return(DreamMessage.Ok(NavBL.ConvertNavPageListToDoc(list))); } else { XDoc doc = NavBL.ComputeNavigationDocument(list, page, (uint)page.ID, 0, true, context.GetParam("width", int.MaxValue)); if (ShowXml(context)) { response.Return(DreamMessage.Ok(doc)); } else { XDoc result = new XDoc("tree"); result.Start("siblings"); // add name of sibling nodes System.Text.StringBuilder nodes = new System.Text.StringBuilder(); ulong homepageId = DekiContext.Current.Instance.HomePageId; foreach (NavBE sibling in list) { if ((sibling.ParentId == page.ParentID) && (sibling.Id != homepageId)) { if (nodes.Length != 0) { nodes.Append(","); } nodes.AppendFormat("n{0}", sibling.Id); } } result.Elem("nodes", nodes.ToString()); // add sibling nodes result.Start("html"); result.Elem("pre", doc["siblings-pre"].Contents); result.Elem("post", doc["siblings-post"].Contents); result.End(); result.End(); response.Return(DreamMessage.Ok(result)); } } yield break; }
public Yield GetPageRating(DreamContext context, DreamMessage request, Result <DreamMessage> response) { UserBE user = DekiContext.Current.User; PageBE page = PageBL_AuthorizePage(context, user, Permissions.READ, false); XDoc ret = RatingBL.GetRatingXml(page, user); response.Return(DreamMessage.Ok(ret)); yield break; }
public Yield GetCommentContent(DreamContext context, DreamMessage request, Result <DreamMessage> response) { PageBE page = null; CommentBE comment = null; GetCommentFromRequest(context, Permissions.READ, out page, out comment); response.Return(DreamMessage.Ok(new MimeType(comment.ContentMimeType), comment.Content)); yield break; }
private static XDoc BuildHtmlSiteMap(PageBE current, XDoc doc, Dictionary <ulong, PageBE> allowedPagesById, Dictionary <ulong, PageBE> filteredPagesById, int depth, bool reverse) { doc.Start("li"); string uri = Utils.AsPublicUiUri(current.Title); List <string> classValues = new List <string>(); if (filteredPagesById.ContainsKey(current.ID)) { classValues.Add("statusRestricted"); } if (current.ID == DekiContext.Current.Instance.HomePageId) { classValues.Add("statusHome"); } doc.Start("a").Attr("rel", "internal").Attr("href", uri).Attr("title", current.Title.AsPrefixedUserFriendlyPath()).Attr("pageid", current.ID); if (classValues.Count > 0) { doc.Attr("class", string.Join(" ", classValues.ToArray())); } doc.Value(current.Title.AsUserFriendlyName()).End(); if (depth > 0 && !ArrayUtil.IsNullOrEmpty(current.ChildPages)) { PageBE[] visibleChildren = Array.FindAll(current.ChildPages, delegate(PageBE child) { return(allowedPagesById.ContainsKey(child.ID)); }); DreamContext context = DreamContext.CurrentOrNull; if (context != null) { DekiContext deki = DekiContext.CurrentOrNull; CultureInfo culture = HttpUtil.GetCultureInfoFromHeader(current.Language ?? ((deki != null) ? deki.Instance.SiteLanguage : string.Empty), context.Culture); string[] paths = new string[visibleChildren.Length]; for (int i = 0; i < visibleChildren.Length; ++i) { paths[i] = XUri.Decode(visibleChildren[i].Title.AsPrefixedDbPath()).Replace("//", "\uFFEF").Replace("/", "\t"); } Array.Sort(paths, visibleChildren, new CompareInfoComparer(culture.CompareInfo)); } if (visibleChildren.Length > 0) { doc.Start("ul"); if (reverse) { Array.Reverse(visibleChildren); } foreach (PageBE p in visibleChildren) { doc = BuildHtmlSiteMap(p, doc, allowedPagesById, filteredPagesById, depth - 1, reverse); } doc.End(); } } doc.End(); return(doc); }
public Yield GetPageTags(DreamContext context, DreamMessage request, Result <DreamMessage> response) { PageBE page = PageBL_AuthorizePage(context, null, Permissions.READ, false); XUri href = DekiContext.Current.ApiUri.At("pages", page.ID.ToString(), "tags"); var tagBL = new TagBL(); XDoc doc = tagBL.GetTagListXml(tagBL.GetTagsForPage(page), "tags", href, false); response.Return(DreamMessage.Ok(doc)); yield break; }
public IList<NavBE> Nav_GetSiblingsAndChildren(PageBE page) { string query = @" /* Nav_GetSiblingsAndChildren */ SELECT page_id, page_namespace, page_title, page_display_name, pages.page_parent as page_parent, restriction_perm_flags, ( SELECT count(C.page_id) FROM pages C WHERE C.page_parent = pages.page_id AND C.page_id != ?HOMEPAGEID AND C.page_parent != ?HOMEPAGEID AND C.page_namespace = ?PAGENS AND C.page_is_redirect = 0 GROUP BY C.page_parent ) AS page_children FROM pages LEFT JOIN restrictions ON page_restriction_id = restriction_id WHERE ( ( pages.page_is_redirect = 0 AND ?HOMEPAGEID != ?PAGEID AND pages.page_parent = ?PAGEPARENT AND pages.page_namespace = ?PAGENS AND pages.page_id != ?HOMEPAGEID ) OR ( pages.page_is_redirect = 0 AND ?HOMEPAGEID = ?PAGEID AND pages.page_parent = 0 AND pages.page_namespace = ?PAGENS ) OR ( ?HOMEPAGEID != ?PAGEID AND pages.page_parent = ?PAGEID AND pages.page_namespace=?PAGENS AND pages.page_is_redirect=0 ) OR pages.page_id = ?PAGEID ) "; DataCommand cmd = Catalog.NewQuery(query) .With("HOMEPAGEID", Head.Pages_HomePageId) .With("PAGEID", page.ID) .With("PAGENS", (int) page.Title.Namespace) .With("PAGEPARENT", page.ParentID); return Nav_GetInternal(cmd); }
//--- Methods --- public IList<NavBE> Nav_GetTree(PageBE page, bool includeAllChildren) { ulong homepageId = Head.Pages_HomePageId; // determine if we need to exclude child pages (if requested page is a child page of Special:) bool includeChildren = (page.Title.Namespace != NS.SPECIAL && page.Title.Namespace != NS.SPECIAL_TALK); // create queries string query = @" /* Nav_GetTree */ SELECT page_id, page_namespace, page_title, page_display_name, pages.page_parent as page_parent, restriction_perm_flags, ({1}) AS page_children FROM pages LEFT JOIN restrictions ON page_restriction_id = restriction_id WHERE {0}"; string subquery = includeChildren ? "SELECT count(C.page_id) FROM pages C WHERE C.page_parent = pages.page_id AND C.page_id != ?HOMEPAGEID AND C.page_parent != ?HOMEPAGEID AND C.page_namespace = ?PAGENS AND C.page_is_redirect = 0 GROUP BY C.page_parent" : "0"; // always include the homepage List<string> where = new List<string>(); where.Add("pages.page_id = ?HOMEPAGEID"); // determine what pages need to be included if(page.ID == homepageId) { // include all children of the homepage in the main namespace where.Add("(pages.page_is_redirect = 0 AND pages.page_parent = 0 AND pages.page_id != ?HOMEPAGEID AND pages.page_namespace = 0)"); } else { // build list of all parent pages, including the current page, but exclusing the homepage, which needs special consideration var parentIdsList = Head.Pages_GetParentIds(page).Where(x => (x != homepageId) && (x != 0)) .Union(new[] {page.ID}) .ToCommaDelimitedString(); // include all parents with the requested page where.Add(string.Format("pages.page_id IN ({0})", parentIdsList)); // check if the parent pages should also contain all their children pages if(includeAllChildren) { if(includeChildren) { // include the children pages of all parents, including the requested page, but excluding the homepage, which needs to be handled differently where.Add(string.Format("(pages.page_is_redirect = 0 AND pages.page_parent IN ({0}) AND pages.page_namespace = ?PAGENS)", parentIdsList)); } // check if for the current namespace, we need to show the children of the homepage if(page.Title.ShowHomepageChildren) { where.Add("(pages.page_is_redirect = 0 AND pages.page_parent = 0 AND pages.page_id != ?HOMEPAGEID AND pages.page_namespace = ?PAGENS)"); } } else { if(includeChildren) { // include only the children of the requested page in the requested namespace where.Add("(pages.page_is_redirect = 0 AND pages.page_parent = ?PAGEID AND pages.page_namespace = ?PAGENS)"); } // check if the requested page is not a child of the homepage; otherwise, we need to be careful about including sibling pages if(page.ParentID != 0) { // include all siblings of the requested page since it's not a child of the homepage where.Add("(pages.page_is_redirect = 0 AND pages.page_parent = ?PAGEPARENT AND pages.page_id != ?PAGEID AND pages.page_namespace = ?PAGENS)"); } else if(page.Title.ShowHomepageChildren) { // include all siblings of the requested page since the requested namespace includes all homepage children pages where.Add("(pages.page_is_redirect = 0 AND pages.page_parent = 0 AND pages.page_id != ?HOMEPAGEID AND pages.page_namespace = ?PAGENS)"); } } } // compose query and execute it query = string.Format(query, string.Join(" OR ", where.ToArray()), subquery); DataCommand cmd = Catalog.NewQuery(query) .With("HOMEPAGEID", Head.Pages_HomePageId) .With("PAGEID", page.ID) .With("PAGENS", (int)page.Title.Namespace) .With("PAGEPARENT", page.ParentID); return Nav_GetInternal(cmd); }
public IList<CommentBE> Comments_GetByPage(PageBE page, CommentFilter searchStatus, bool includePageDescendants, uint? postedByUserId, SortDirection datePostedSortDir, uint? offset, uint? limit, out uint totalComments) { List<CommentBE> comments = new List<CommentBE>(); uint totalCommentsTemp = 0; string joins = string.Empty; if(includePageDescendants) { joins = "JOIN pages \n\tON comments.cmnt_page_id = pages.page_id"; } string whereClauses = "\n 1=1"; switch(searchStatus) { case CommentFilter.DELETED: whereClauses += "\n AND cmnt_delete_date is not null"; break; case CommentFilter.NONDELETED: whereClauses += "\n AND cmnt_delete_date is null"; break; } if(includePageDescendants) { whereClauses += @" AND( ( (( ?TITLE = '' AND pages.page_title != '') OR (LEFT(pages.page_title, CHAR_LENGTH(?TITLE) + 1) = CONCAT(?TITLE, '/') AND SUBSTRING(pages.page_title, CHAR_LENGTH(?TITLE) + 2, 1) != '/')) AND pages.page_namespace = ?NS AND pages.page_is_redirect = 0 ) OR pages.page_id = ?PAGEID)"; } else { whereClauses += "\n AND cmnt_page_id = ?PAGEID"; } if(postedByUserId != null) { whereClauses += "\n AND cmnt_poster_user_id = ?POSTERID"; } string orderby = string.Empty; if(datePostedSortDir != SortDirection.UNDEFINED) { orderby = string.Format("ORDER BY cmnt_create_date {0}, cmnt_id {0}", datePostedSortDir.ToString()); } List<uint> userids = new List<uint>(); string query = string.Format(@" /* Comments_GetByPage */ SELECT SQL_CALC_FOUND_ROWS comments.* FROM comments {0} WHERE {1} {2} LIMIT ?COUNT OFFSET ?OFFSET; select found_rows() as totalcomments;" , joins, whereClauses, orderby); Catalog.NewQuery(query) .With("PAGEID", page.ID) .With("TITLE", page.Title.AsUnprefixedDbPath()) .With("NS", (int)page.Title.Namespace) .With("POSTERID", postedByUserId) .With("COUNT", limit ?? UInt32.MaxValue) .With("OFFSET", offset ?? 0) .Execute(delegate(IDataReader dr) { while(dr.Read()) { CommentBE c = Comments_Populate(dr); if(c.DeleterUserId != null) { userids.Add(c.DeleterUserId ?? 0); } if(c.LastEditUserId != null) { userids.Add(c.LastEditUserId ?? 0); } userids.Add(c.PosterUserId); comments.Add(c); } if(dr.NextResult() && dr.Read()) { totalCommentsTemp = DbUtils.Convert.To<uint>(dr["totalcomments"]) ?? 0; } }); totalComments = totalCommentsTemp; return comments; }
public ulong Pages_Insert(PageBE page, ulong restoredPageID) { var query = @" /* Pages_Insert */ INSERT INTO pages ({0}page_namespace, page_title, page_text, page_comment, page_user_id, page_timestamp, page_is_redirect, page_minor_edit, page_is_new, page_touched, page_usecache, page_toc, page_tip, page_parent, page_restriction_id, page_content_type, page_language, page_display_name, page_etag, page_revision) VALUES ({1}?NAMESPACE, ?TITLE, ?PAGETEXT, ?PAGECOMMENT, ?USERID, ?PAGETIMESTAMP, ?ISREDIRECT, ?MINOREDIT, ?ISNEW, ?TOUCHED, ?USECACHE, '', ?TIP, ?PARENT, ?RESTRICTIONID, ?CONTENTTYPE, ?LANGUAGE, ?DISPLAYNAME, ?ETAG, ?REVISION); {2} REPLACE INTO page_viewcount (page_id,page_counter) VALUES (@page_id,0); SELECT @page_id"; query = restoredPageID != 0 ? string.Format(query, "page_id,", "?PAGE_ID,", "SELECT @page_id := " + restoredPageID + " as page_id;") : string.Format(query, "", "", "SELECT @page_id := LAST_INSERT_ID() as page_id;"); // create the insertion command ulong pageId = 0; Catalog.NewQuery(query) .With("PAGE_ID", restoredPageID) .With("NAMESPACE", page.Title.Namespace) .With("TITLE", page.Title.AsUnprefixedDbPath()) .With("PAGETEXT", page.GetText(this.Head)) .With("PAGECOMMENT", page.Comment) .With("USERID", page.UserID) .With("PAGETIMESTAMP", page._TimeStamp) .With("ISREDIRECT", page.IsRedirect) .With("MINOREDIT", page.MinorEdit) .With("ISNEW", page.IsNew) .With("TOUCHED", page._Touched) .With("USECACHE", page.UseCache) .With("TIP", page.TIP) .With("PARENT", page.ParentID) .With("RESTRICTIONID", page.RestrictionID) .With("CONTENTTYPE", page.ContentType) .With("LANGUAGE", page.Language) .With("DISPLAYNAME", page.Title.DisplayName) .With("PAGEID", restoredPageID) .With("ETAG", page.Etag) .With("REVISION", page.Revision) .Execute(delegate(IDataReader dr) { if(dr.Read()) { pageId = dr.Read<ulong>("page_id"); } }); return pageId; }
public void RecentChanges_Insert(DateTime timestamp, PageBE page, UserBE user, string comment, ulong lastoldid, RC type, uint movedToNS, string movedToTitle, bool isMinorChange, uint transactionId) { string dbtimestamp = DbUtils.ToString(timestamp); string pageTitle = String.Empty; NS pageNamespace = NS.MAIN; ulong pageID = 0; uint userID = 0; if (page != null) { pageTitle = page.Title.AsUnprefixedDbPath() ; pageNamespace = page.Title.Namespace; pageID = page.ID; } if (user != null) { userID = user.ID; } string q = "/* RecentChanges_Insert */"; if(lastoldid > 0) { q += @" UPDATE recentchanges SET rc_this_oldid = ?LASTOLDID WHERE rc_namespace = ?NS AND rc_title = ?TITLE AND rc_this_oldid=0;"; } q += @" INSERT INTO recentchanges (rc_timestamp, rc_cur_time, rc_user, rc_namespace, rc_title, rc_comment, rc_cur_id, rc_this_oldid, rc_last_oldid, rc_type, rc_moved_to_ns, rc_moved_to_title, rc_minor, rc_transaction_id) VALUES (?TS, ?TS, ?USER, ?NS, ?TITLE, ?COMMENT, ?CURID, 0, ?LASTOLDID, ?TYPE, ?MOVEDTONS, ?MOVEDTOTITLE, ?MINOR, ?TRANID); "; if(!string.IsNullOrEmpty(comment) && comment.Length > MAXCOMMENTLENGTH) { string segment1 = comment.Substring(0, MAXCOMMENTLENGTH / 2); string segment2 = comment.Substring(comment.Length - MAXCOMMENTLENGTH / 2 + 3); comment = string.Format("{0}...{1}", segment1, segment2); } Catalog.NewQuery(q) .With("TS", dbtimestamp) .With("USER", userID) .With("NS", pageNamespace) .With("TITLE", pageTitle) .With("COMMENT", comment) .With("CURID", pageID) .With("LASTOLDID", lastoldid) .With("TYPE", (uint) type) .With("MOVEDTONS", movedToNS) .With("MOVEDTOTITLE", movedToTitle) .With("MINOR", isMinorChange ? 1 : 0) .With("TRANID", transactionId) .Execute(); }
public void Pages_Update(PageBE page) { // Update page text only if it has been set string updatePageText = String.Empty; if(page.IsTextPopulated) { updatePageText = ", page_text = ?PAGETEXT"; } string query = String.Format(@" /* Pages_Update */ update pages SET page_namespace = ?NAMESPACE, page_title = ?TITLE, page_comment = ?PAGECOMMENT, page_user_id = ?USERID, page_timestamp = ?PAGETIMESTAMP, page_is_redirect = ?ISREDIRECT, page_minor_edit = ?MINOREDIT, page_is_new = ?ISNEW, page_touched = ?TOUCHED, page_usecache = ?USECACHE, page_tip = ?TIP, page_parent = ?PARENT, page_restriction_id = ?RESTRICTIONID, page_content_type = ?CONTENTTYPE, page_language = ?LANGUAGE, page_display_name = ?DISPLAYNAME, page_etag = ?ETAG, page_revision = ?REVISION {0} where page_id = ?PAGEID ", updatePageText); DataCommand cmd = Catalog.NewQuery(query) .With("PAGEID", page.ID) .With("NAMESPACE", (int)page.Title.Namespace) .With("TITLE", page.Title.AsUnprefixedDbPath()) .With("PAGECOMMENT", page.Comment) .With("USERID", page.UserID) .With("PAGETIMESTAMP", page._TimeStamp) .With("ISREDIRECT", page.IsRedirect) .With("MINOREDIT", page.MinorEdit) .With("ISNEW", page.IsNew) .With("TOUCHED", page._Touched) .With("USECACHE", page.UseCache) .With("TIP", page.TIP) .With("PARENT", page.ParentID) .With("RESTRICTIONID", page.RestrictionID) .With("CONTENTTYPE", page.ContentType) .With("LANGUAGE", page.Language) .With("DISPLAYNAME", page.Title.DisplayName) .With("ETAG", page.Etag) .With("REVISION", page.Revision); if(page.IsTextPopulated) { cmd.With("PAGETEXT", page.GetText(this.Head)); } cmd.Execute(); }
public IList<ulong> Pages_GetParentIds(PageBE page) { //MaxM: This query returns 10 segments of a hierarchy without using a loop or titles and can be query cached. Please don't submit to the dailywtf. :) string query = @" /* Pages_GetParentIds */ select p0.page_id, p0.page_parent, p1.page_parent, p2.page_parent, p3.page_parent, p4.page_parent, p5.page_parent, p6.page_parent, p7.page_parent, p8.page_parent, p9.page_parent from pages p0 left join pages p1 on p0.page_parent = p1.page_id left join pages p2 on p1.page_parent = p2.page_id left join pages p3 on p2.page_parent = p3.page_id left join pages p4 on p3.page_parent = p4.page_id left join pages p5 on p4.page_parent = p5.page_id left join pages p6 on p5.page_parent = p6.page_id left join pages p7 on p6.page_parent = p7.page_id left join pages p8 on p7.page_parent = p8.page_id left join pages p9 on p8.page_parent = p9.page_id where p0.page_id = ?PAGEID;"; ulong homepageid = Head.Pages_HomePageId; int counter = 0; ulong id = page.ID; bool first = true; Dictionary<ulong, object> dupeChecker = new Dictionary<ulong, object>(); List<ulong> result = new List<ulong>(16); // loop until we've found all the parents while(counter++ < 20) { // execute query for given page bool done = false; Catalog.NewQuery(query) .With("PAGEID", id) .Execute(delegate(IDataReader dr) { if(dr.Read()) { for(int i = first ? 0 : 1; i < dr.FieldCount; i++) { ulong parentPageId = DbUtils.Convert.To<ulong>(dr.GetValue(i)) ?? 0; if(parentPageId == 0) { // no valid parent found if(page.Title.Namespace == NS.MAIN) { // add the homepage for pages in the MAIN namespace result.Add(homepageid); } done = true; break; } else { if(!dupeChecker.ContainsKey(parentPageId)) { result.Add(parentPageId); dupeChecker[parentPageId] = null; } else { //Cycle detected done = true; } } } } else { done = true; } }); // check if done if(done) { return result; } // continue with last parent id id = result[result.Count - 1]; first = false; } throw new Exception(string.Format("GetParentPages failed: too many iterations. Starting id: {0} Parent chain: {1}", page.ID, result.ToCommaDelimitedString())); }
private PageBE Pages_PopulatePage(IDataReader dr) { PageBE p = new PageBE(); p._Comment = dr.Read<byte[]>("page_comment"); p._DisplayName = dr.Read<string>("page_display_name"); p._Namespace = dr.Read<ushort>("page_namespace"); p._TimeStamp = dr.Read<string>("page_timestamp"); p._Title = dr.Read<string>("page_title"); p._Touched = dr.Read<string>("page_touched"); p.ContentType = dr.Read<string>("page_content_type"); p.ID = dr.Read<ulong>("page_id"); p.IsNew = dr.Read<bool>("page_is_new"); p.IsHidden = dr.Read<bool>("page_is_hidden"); p.IsRedirect = dr.Read<bool>("page_is_redirect"); p.Language = dr.Read<string>("page_language"); p.Meta = dr.Read<string>("page_meta"); p.MinorEdit = dr.Read<bool>("page_minor_edit"); p.ParentID = dr.Read<ulong>("page_parent"); p.RestrictionID = dr.Read<uint>("page_restriction_id"); p.Revision = dr.Read<uint>("page_revision"); p.TextLength = dr.Read<int>("page_text_length"); p.TIP = dr.Read<string>("page_tip"); p.UseCache = dr.Read<bool>("page_usecache"); p.UserID = dr.Read<uint>("page_user_id"); p.Etag = dr.Read<string>("page_etag"); return p; }
public void Pages_GetDescendants(PageBE rootPage, string language, bool filterOutRedirects, out IList<PageBE> pages, out Dictionary<ulong, IList<ulong>> childrenInfo, int limit) { List<PageBE> tempPages = new List<PageBE>(); Dictionary<ulong, IList<ulong>> children = new Dictionary<ulong, IList<ulong>>(); string q = string.Format(@" /* Pages_GetDescendants */ SET group_concat_max_len = @@max_allowed_packet; SELECT {0}, ( if( p.page_title = '', ( /*Find children of root page*/ SELECT cast(group_concat( p1.page_id, '') as char) FROM pages p1 WHERE p1.page_parent = 0 AND p.page_title = '' AND p1.page_namespace = ?NS AND p.page_id <> p1.page_id AND (?LANGUAGE IS NULL OR p1.page_language = ?LANGUAGE OR p1.page_language = '') GROUP BY p1.page_parent ), ( /* Find children of non-root pages */ SELECT cast(group_concat( p1.page_id, '') as char) FROM pages p1 WHERE p1.page_parent = p.page_id AND p.page_title <> '' AND p1.page_namespace = ?NS AND p.page_id <> p1.page_id AND (?LANGUAGE IS NULL OR p1.page_language = ?LANGUAGE OR p1.page_language = '') GROUP BY p1.page_parent ) ) ) AS page_children FROM pages p WHERE ( ((?TITLE = '' AND p.page_title != '') OR (LEFT(p.page_title, CHAR_LENGTH(?TITLE) + 1) = CONCAT(?TITLE, '/') AND SUBSTRING(p.page_title, CHAR_LENGTH(?TITLE) + 2, 1) != '/')) AND p.page_namespace = ?NS AND (?LANGUAGE IS NULL OR p.page_language = ?LANGUAGE OR p.page_language = '') {1} ) OR p.page_id = ?PAGEID LIMIT ?LIMIT;" , PAGEFIELDS, filterOutRedirects ? "AND p.page_is_redirect = 0" : string.Empty); Catalog.NewQuery(q) .With("PAGEID", rootPage.ID) .With("TITLE", rootPage.Title.AsUnprefixedDbPath()) .With("NS", (int)rootPage.Title.Namespace) .With("LANGUAGE", language) .With("LIMIT", limit) .Execute(delegate(IDataReader dr) { while(dr.Read()) { PageBE p = Pages_PopulatePage(dr); tempPages.Add(p); List<ulong> childrenIds = new List<ulong>(); string childrenStr = dr["page_children"] as string; if(childrenStr != null) { foreach(string s in childrenStr.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { childrenIds.Add(ulong.Parse(s)); } } children[p.ID] = childrenIds; } }); if(tempPages.Count >= limit) { throw new TooManyResultsException(); } pages = tempPages; childrenInfo = children; }
public void Links_UpdateLinksForPage(PageBE page, IList<ulong> outboundLinks, IList<string> brokenLinks) { StringBuilder query = new StringBuilder(@" /* Links_UpdateLinksForPage */ DELETE FROM links WHERE l_from = ?PAGEID; DELETE FROM brokenlinks WHERE bl_from = ?PAGEID; "); // build page's outbound links query if(!ArrayUtil.IsNullOrEmpty(outboundLinks)) { query.Append(@" INSERT IGNORE INTO links (l_from, l_to) VALUES "); for(int i = 0; i < outboundLinks.Count; i++) { query.AppendFormat("{0}(?PAGEID, {1})", i > 0 ? "," : "", outboundLinks[i]); } query.Append(";"); } // build page's broken links query if(!ArrayUtil.IsNullOrEmpty(brokenLinks)) { query.Append(@" INSERT IGNORE INTO brokenlinks (bl_from, bl_to) VALUES "); for(int i = 0; i < brokenLinks.Count; i++) { query.AppendFormat("{0}(?PAGEID, '{1}')", i > 0 ? "," : "", DataCommand.MakeSqlSafe(brokenLinks[i])); } query.Append(";"); } // build query to update any broken links that point to this page query.Append(@" INSERT IGNORE INTO links (l_from, l_to) SELECT brokenlinks.bl_from, ?PAGEID FROM brokenlinks WHERE bl_to = ?TITLE; DELETE FROM brokenlinks WHERE bl_to = ?TITLE;" ); Catalog.NewQuery(query.ToString()) .With("PAGEID", page.ID) .With("TITLE", page.Title.AsPrefixedDbPath()) .Execute(); }