public override void NormalizeClientModel(ServiceClient client) { if (client == null) { throw new ArgumentNullException("client"); } base.NormalizeClientModel(client); foreach (var method in client.Methods) { var scope = new ScopeProvider(); foreach (var parameter in method.Parameters) { if (parameter.ClientProperty != null) { parameter.Name = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", method.Group == null ? "this" : "this.Client", parameter.ClientProperty.Name); } else { parameter.Name = scope.GetVariableName(parameter.Name); } } } }
public void DisposeScopeProvider() { // Setup var called = false; Action action = () => called = true; var scopeProvider = new ScopeProvider(action); // Execute scopeProvider.Dispose(); // Assert Assert.IsTrue(called); }
public void Delete(TItem item, int userId = Cms.Core.Constants.Security.SuperUserId) { using (IScope scope = ScopeProvider.CreateScope()) { EventMessages eventMessages = EventMessagesFactory.Get(); DeletingNotification <TItem> deletingNotification = GetDeletingNotification(item, eventMessages); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; } scope.WriteLock(WriteLockIds); // all descendants are going to be deleted TItem[] descendantsAndSelf = GetDescendants(item.Id, true) .ToArray(); TItem[] deleted = descendantsAndSelf; // all impacted (through composition) probably lose some properties // don't try to be too clever here, just report them all // do this before anything is deleted TItem[] changed = descendantsAndSelf.SelectMany(xx => GetComposedOf(xx.Id)) .Distinct() .Except(descendantsAndSelf) .ToArray(); // delete content DeleteItemsOfTypes(descendantsAndSelf.Select(x => x.Id)); // Next find all other document types that have a reference to this content type IEnumerable <TItem> referenceToAllowedContentTypes = GetAll().Where(q => q.AllowedContentTypes.Any(p => p.Id.Value == item.Id)); foreach (TItem reference in referenceToAllowedContentTypes) { reference.AllowedContentTypes = reference.AllowedContentTypes.Where(p => p.Id.Value != item.Id); var changedRef = new List <ContentTypeChange <TItem> >() { new ContentTypeChange <TItem>(reference, ContentTypeChangeTypes.RefreshMain) }; // Fire change event scope.Notifications.Publish(GetContentTypeChangedNotification(changedRef, eventMessages)); } // finally delete the content type // - recursively deletes all descendants // - deletes all associated property data // (contents of any descendant type have been deleted but // contents of any composed (impacted) type remain but // need to have their property data cleared) Repository.Delete(item); ContentTypeChange <TItem>[] changes = descendantsAndSelf.Select(x => new ContentTypeChange <TItem>(x, ContentTypeChangeTypes.Remove)) .Concat(changed.Select(x => new ContentTypeChange <TItem>(x, ContentTypeChangeTypes.RefreshMain | ContentTypeChangeTypes.RefreshOther))) .ToArray(); // Publish this in scope, see comment at GetContentTypeRefreshedNotification for more info. _eventAggregator.Publish(GetContentTypeRefreshedNotification(changes, eventMessages)); scope.Notifications.Publish(GetContentTypeChangedNotification(changes, eventMessages)); DeletedNotification <TItem> deletedNotification = GetDeletedNotification(deleted.DistinctBy(x => x.Id), eventMessages); deletedNotification.WithStateFrom(deletingNotification); scope.Notifications.Publish(deletedNotification); Audit(AuditType.Delete, userId, item.Id); scope.Complete(); } }
public override void NormalizeClientModel(ServiceClient client) { if (client == null) { throw new ArgumentNullException("client"); } base.NormalizeClientModel(client); foreach (var method in client.Methods) { if (method.Group != null) { method.Group = method.Group.ToCamelCase(); } var scope = new ScopeProvider(); foreach (var parameter in method.Parameters) { if (parameter.ClientProperty != null) { parameter.Name = string.Format(CultureInfo.InvariantCulture, "{0}.get{1}()", method.Group == null ? "this" : "this.client", parameter.ClientProperty.Name.ToPascalCase()); } else { parameter.Name = scope.GetVariableName(parameter.Name); } if (!parameter.IsRequired) { parameter.Type = WrapPrimitiveType(parameter.Type); } } } }
/// <summary>Entry point for embedded applications.</summary> /// <remarks> /// Entry point for embedded applications. This method attaches /// to the given /// <see cref="Rhino.ContextFactory">Rhino.ContextFactory</see> /// with the given scope. No /// I/O redirection is performed as with /// <see cref="Main(string[])">Main(string[])</see> /// . /// </remarks> public static Program MainEmbedded(ContextFactory factory, ScopeProvider scopeProvider, string title) { return MainEmbeddedImpl(factory, scopeProvider, title); }
public void TestMultipleOneToOne() { using (var scope = ScopeProvider.CreateScope()) { var tA1A = new ThingA1Dto { Id = 1, Name = "a1_a" }; scope.Database.Insert(tA1A); var tA1B = new ThingA1Dto { Id = 2, Name = "a1_b" }; scope.Database.Insert(tA1B); var tA1C = new ThingA1Dto { Id = 3, Name = "a1_c" }; scope.Database.Insert(tA1C); var tA2A = new ThingA2Dto { Id = 1, Name = "a2_a" }; scope.Database.Insert(tA2A); var tA2B = new ThingA2Dto { Id = 2, Name = "a2_b" }; scope.Database.Insert(tA2B); var tA2C = new ThingA2Dto { Id = 3, Name = "a2_c" }; scope.Database.Insert(tA2C); var tA3A = new ThingA3Dto { Id = 1, Name = "a3_a" }; scope.Database.Insert(tA3A); var tA3B = new ThingA3Dto { Id = 2, Name = "a3_b" }; scope.Database.Insert(tA3B); var k1 = new ThingA12Dto { Name = "a", Thing1Id = tA1A.Id, Thing2Id = tA2A.Id }; scope.Database.Insert(k1); var k2 = new ThingA12Dto { Name = "B", Thing1Id = tA1A.Id, Thing2Id = tA2B.Id }; scope.Database.Insert(k2); var sql = @"SELECT a1.id, a1.name, a2.id AS T2A__Id, a2.name AS T2A__Name, a3.id AS T2A__T3__Id, a3.name AS T2A__T3__Name, a2x.id AS T2B__Id, a2x.name AS T2B__Name, a3x.id AS T2B__T3__Id, a3x.name AS T2B__T3__Name FROM zbThingA1 a1 JOIN zbThingA12 a12 ON a1.id=a12.thing1id AND a12.name='a' JOIN zbThingA2 a2 ON a12.thing2id=a2.id JOIN zbThingA3 a3 ON a2.id=a3.id JOIN zbThingA12 a12x ON a1.id=a12x.thing1id AND a12x.name='b' JOIN zbThingA2 a2x ON a12x.thing2id=a2x.id JOIN zbThingA3 a3x ON a2x.id=a3x.id "; var ts = scope.Database.Fetch <ThingA1Dto>(sql); Assert.AreEqual(1, ts.Count); var t = ts.First(); Assert.AreEqual("a1_a", t.Name); Assert.AreEqual("a2_a", t.T2A.Name); Assert.AreEqual("a2_b", t.T2B.Name); Assert.AreEqual("a3_a", t.T2A.T3.Name); Assert.AreEqual("a3_b", t.T2B.T3.Name); scope.Complete(); } }
public void Can_Get_Tags_For_Content_By_Key() { IScopeProvider provider = ScopeProvider; using (ScopeProvider.CreateScope()) { // create data to relate to // We have to create and save a template, otherwise we get an FK violation on contentType. Template template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); ContentType contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); ContentTypeRepository.Save(contentType); Content content1 = ContentBuilder.CreateSimpleContent(contentType); DocumentRepository.Save(content1); Content content2 = ContentBuilder.CreateSimpleContent(contentType); DocumentRepository.Save(content2); TagRepository repository = CreateRepository(provider); Tag[] tags = new[] { new Tag { Text = "tag1", Group = "test" }, new Tag { Text = "tag2", Group = "test" }, new Tag { Text = "tag3", Group = "test" }, new Tag { Text = "tag4", Group = "test" } }; repository.Assign( content1.Id, contentType.PropertyTypes.First().Id, tags, false); Tag[] tags2 = new[] { new Tag { Text = "tag1", Group = "test" }, new Tag { Text = "tag2", Group = "test" } }; repository.Assign( content2.Id, contentType.PropertyTypes.First().Id, tags2, false); // get by key IEnumerable <ITag> result = repository.GetTagsForEntity(content2.Key); Assert.AreEqual(2, result.Count()); } }
public IDisposable BeginScope <TState>(TState state) => ScopeProvider?.Push(state) ?? NullScope.Instance;
public void PathTests() { // unless noted otherwise, no changes / 7.2.8 var provider = TestObjects.GetScopeProvider(Logger); using (var scope = ScopeProvider.CreateScope()) { var repository = new ScriptRepository(_fileSystems, Mock.Of <IContentSection>()); var script = new Script("test-path-1.js") { Content = "// script" }; repository.Save(script); Assert.IsTrue(_fileSystem.FileExists("test-path-1.js")); Assert.AreEqual("test-path-1.js", script.Path); Assert.AreEqual("/scripts/test-path-1.js", script.VirtualPath); //ensure you can prefix the same path as the root path name script = new Script("scripts/path-2/test-path-2.js") { Content = "// script" }; repository.Save(script); Assert.IsTrue(_fileSystem.FileExists("scripts/path-2/test-path-2.js")); Assert.AreEqual("scripts\\path-2\\test-path-2.js", script.Path); Assert.AreEqual("/scripts/scripts/path-2/test-path-2.js", script.VirtualPath); script = new Script("path-2/test-path-2.js") { Content = "// script" }; repository.Save(script); Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-2.js")); Assert.AreEqual("path-2\\test-path-2.js", script.Path); // fixed in 7.3 - 7.2.8 does not update the path Assert.AreEqual("/scripts/path-2/test-path-2.js", script.VirtualPath); script = repository.Get("path-2/test-path-2.js"); Assert.IsNotNull(script); Assert.AreEqual("path-2\\test-path-2.js", script.Path); Assert.AreEqual("/scripts/path-2/test-path-2.js", script.VirtualPath); script = new Script("path-2\\test-path-3.js") { Content = "// script" }; repository.Save(script); Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-3.js")); Assert.AreEqual("path-2\\test-path-3.js", script.Path); Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath); script = repository.Get("path-2/test-path-3.js"); Assert.IsNotNull(script); Assert.AreEqual("path-2\\test-path-3.js", script.Path); Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath); script = repository.Get("path-2\\test-path-3.js"); Assert.IsNotNull(script); Assert.AreEqual("path-2\\test-path-3.js", script.Path); Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath); script = new Script("\\test-path-4.js") { Content = "// script" }; Assert.Throws <FileSecurityException>(() => // fixed in 7.3 - 7.2.8 used to strip the \ { repository.Save(script); }); script = repository.Get("missing.js"); Assert.IsNull(script); // fixed in 7.3 - 7.2.8 used to... Assert.Throws <FileSecurityException>(() => { script = repository.Get("\\test-path-4.js"); // outside the filesystem, does not exist }); Assert.Throws <FileSecurityException>(() => { script = repository.Get("../packages.config"); // outside the filesystem, exists }); } }
public IReadOnlyDictionary <Udi, IEnumerable <string> > GetReferences(int id) { using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true); return(_dataTypeRepository.FindUsages(id)); }
public IEnumerable <EntityContainer> GetContainers(int[] containerIds) { using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true); return(_dataTypeContainerRepository.GetMany(containerIds)); }
public IEnumerable <EntityContainer> GetContainers(string name, int level) { using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true); return(_dataTypeContainerRepository.Get(name, level)); }
public EntityContainer?GetContainer(Guid containerId) { using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true); return(_dataTypeContainerRepository.Get(containerId)); }
public void Read_Lock_Waits_For_Write_Lock() { var locksCompleted = 0; var t1 = Task.Run(() => { using (var scope = ScopeProvider.CreateScope()) { var realScope = (Scope)scope; Console.WriteLine("Write lock A"); // This will acquire right away realScope.WriteLock(TimeSpan.FromMilliseconds(2000), Constants.Locks.ContentTree); Thread.Sleep(4000); // Wait less than the Read Lock B timeout scope.Complete(); Interlocked.Increment(ref locksCompleted); Console.WriteLine("Finished Write lock A"); } }); Thread.Sleep(500); // 100% sure task 1 starts first var t2 = Task.Run(() => { using (var scope = ScopeProvider.CreateScope()) { var realScope = (Scope)scope; Console.WriteLine("Read lock B"); // This will wait for the write lock to release Assert.DoesNotThrow(() => realScope.ReadLock(TimeSpan.FromMilliseconds(6000), Constants.Locks.ContentTree)); Assert.GreaterOrEqual(locksCompleted, 1); scope.Complete(); Interlocked.Increment(ref locksCompleted); Console.WriteLine("Finished Read lock B"); } }); var t3 = Task.Run(() => { using (var scope = ScopeProvider.CreateScope()) { var realScope = (Scope)scope; Console.WriteLine("Read lock C"); // This will wait for the write lock to release Assert.DoesNotThrow(() => realScope.ReadLock(TimeSpan.FromMilliseconds(6000), Constants.Locks.ContentTree)); Assert.GreaterOrEqual(locksCompleted, 1); scope.Complete(); Interlocked.Increment(ref locksCompleted); Console.WriteLine("Finished Read lock C"); } }); Task.WaitAll(t1, t2, t3); Assert.AreEqual(3, locksCompleted); }
public void TestScopeMany(bool complete) { var umbracoContext = GetUmbracoContext("http://example.com/", setSingleton: true); // sanity checks Assert.AreSame(umbracoContext, Umbraco.Web.Composing.Current.UmbracoContext); Assert.AreSame(XmlStore, ((PublishedContentCache)umbracoContext.Content).XmlStore); // create document type var contentType = new ContentType(-1) { Alias = "CustomDocument", Name = "Custom Document" }; Current.Services.ContentTypeService.Save(contentType); // wire cache refresher _distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of <IUmbracoContextFactory>(), Mock.Of <ILogger>()); _distributedCacheBinder.BindEvents(true); // check xml in context = "before" var xml = XmlInContext; var beforeXml = xml; var beforeOuterXml = beforeXml.OuterXml; var item = new Content("name", -1, contentType); const int count = 10; var ids = new int[count]; var clones = 0; SafeXmlReaderWriter.Cloning = () => { clones++; }; Console.WriteLine("Xml Before:"); Console.WriteLine(xml.OuterXml); using (var scope = ScopeProvider.CreateScope()) { Current.Services.ContentService.SaveAndPublish(item); for (var i = 0; i < count; i++) { var temp = new Content("content_" + i, -1, contentType); Current.Services.ContentService.SaveAndPublish(temp); ids[i] = temp.Id; } // this should never change Assert.AreEqual(beforeOuterXml, beforeXml.OuterXml); xml = XmlMaster; Assert.IsNotNull(xml); Console.WriteLine("Xml InScope (before complete):"); Console.WriteLine(xml.OuterXml); Assert.AreEqual(beforeOuterXml, xml.OuterXml); if (complete) { scope.Complete(); } xml = XmlMaster; Assert.IsNotNull(xml); Console.WriteLine("Xml InScope (after complete):"); Console.WriteLine(xml.OuterXml); Assert.AreEqual(beforeOuterXml, xml.OuterXml); } var scopeProvider = ScopeProvider; Assert.IsNotNull(scopeProvider); // ambient scope may be null, or maybe not, depending on whether the code that // was called did proper scoped work, or some direct (NoScope) use of the database Assert.IsNull(scopeProvider.AmbientContext); // limited number of clones! Assert.AreEqual(complete ? 1 : 0, clones); // this should never change Assert.AreEqual(beforeOuterXml, beforeXml.OuterXml); xml = XmlMaster; Assert.IsNotNull(xml); Console.WriteLine("Xml After:"); Console.WriteLine(xml.OuterXml); if (complete) { var node = xml.GetElementById(item.Id.ToString()); Assert.IsNotNull(node); for (var i = 0; i < 10; i++) { node = xml.GetElementById(ids[i].ToString()); Assert.IsNotNull(node); } } else { Assert.AreEqual(beforeOuterXml, xml.OuterXml); // nothing has changed! } }
public void TestScope(bool complete) { var umbracoContext = GetUmbracoContext("http://example.com/", setSingleton: true); // sanity checks Assert.AreSame(umbracoContext, Umbraco.Web.Composing.Current.UmbracoContext); Assert.AreSame(XmlStore, ((PublishedContentCache)umbracoContext.Content).XmlStore); // create document type, document var contentType = new ContentType(-1) { Alias = "CustomDocument", Name = "Custom Document" }; Current.Services.ContentTypeService.Save(contentType); var item = new Content("name", -1, contentType); // wire cache refresher _distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of <IUmbracoContextFactory>(), Mock.Of <ILogger>()); _distributedCacheBinder.BindEvents(true); // check xml in context = "before" var xml = XmlInContext; var beforeXml = xml; var beforeOuterXml = beforeXml.OuterXml; Console.WriteLine("Xml Before:"); Console.WriteLine(xml.OuterXml); // event handler var evented = 0; _onPublishedAssertAction = () => { evented++; // should see the changes in context, not in master xml = XmlInContext; Assert.AreNotSame(beforeXml, xml); Console.WriteLine("Xml Event:"); Console.WriteLine(xml.OuterXml); var node = xml.GetElementById(item.Id.ToString()); Assert.IsNotNull(node); xml = XmlMaster; Assert.AreSame(beforeXml, xml); Assert.AreEqual(beforeOuterXml, xml.OuterXml); }; ContentService.Published += OnPublishedAssert; using (var scope = ScopeProvider.CreateScope()) { Current.Services.ContentService.SaveAndPublish(item); // should create an xml clone item.Name = "changed"; Current.Services.ContentService.SaveAndPublish(item); // should re-use the xml clone // this should never change Assert.AreEqual(beforeOuterXml, beforeXml.OuterXml); // this does not change, other thread don't see the changes xml = XmlMaster; Assert.AreSame(beforeXml, xml); Console.WriteLine("XmlInternal During:"); Console.WriteLine(xml.OuterXml); Assert.AreEqual(beforeOuterXml, xml.OuterXml); // this does not change during the scope (only in events) // because it is the events that trigger the changes xml = XmlInContext; Assert.IsNotNull(xml); Assert.AreSame(beforeXml, xml); Assert.AreEqual(beforeOuterXml, xml.OuterXml); // note // this means that, as long as ppl don't create scopes, they'll see their // changes right after SaveAndPublish, but if they create scopes, // they will have to wail until the scope is completed, ie wait until the // events trigger, to use eg GetUrl etc if (complete) { scope.Complete(); } } //The reason why there is only 1 event occuring is because we are publishing twice for the same event for the same //object and the scope deduplicates the events(uses the latest) Assert.AreEqual(complete? 1 : 0, evented); // this should never change Assert.AreEqual(beforeOuterXml, beforeXml.OuterXml); xml = XmlInContext; Console.WriteLine("Xml After:"); Console.WriteLine(xml.OuterXml); if (complete) { var node = xml.GetElementById(item.Id.ToString()); Assert.IsNotNull(node); } else { Assert.AreSame(beforeXml, xml); Assert.AreEqual(beforeOuterXml, xml.OuterXml); // nothing has changed! } xml = XmlMaster; if (complete) { var node = xml.GetElementById(item.Id.ToString()); Assert.IsNotNull(node); } else { Assert.AreSame(beforeXml, xml); Assert.AreEqual(beforeOuterXml, xml.OuterXml); // nothing has changed! } }
/// <inheritdoc /> public IAuditEntry Write(int performingUserId, string perfomingDetails, string performingIp, DateTime eventDateUtc, int affectedUserId, string?affectedDetails, string eventType, string eventDetails) { if (performingUserId < 0 && performingUserId != Cms.Core.Constants.Security.SuperUserId) { throw new ArgumentOutOfRangeException(nameof(performingUserId)); } if (string.IsNullOrWhiteSpace(perfomingDetails)) { throw new ArgumentException("Value cannot be null or whitespace.", nameof(perfomingDetails)); } if (string.IsNullOrWhiteSpace(eventType)) { throw new ArgumentException("Value cannot be null or whitespace.", nameof(eventType)); } if (string.IsNullOrWhiteSpace(eventDetails)) { throw new ArgumentException("Value cannot be null or whitespace.", nameof(eventDetails)); } //we need to truncate the data else we'll get SQL errors affectedDetails = affectedDetails?.Substring(0, Math.Min(affectedDetails.Length, Constants.Audit.DetailsLength)); eventDetails = eventDetails.Substring(0, Math.Min(eventDetails.Length, Constants.Audit.DetailsLength)); //validate the eventType - must contain a forward slash, no spaces, no special chars var eventTypeParts = eventType.ToCharArray(); if (eventTypeParts.Contains('/') == false || eventTypeParts.All(c => char.IsLetterOrDigit(c) || c == '/' || c == '-') == false) { throw new ArgumentException(nameof(eventType) + " must contain only alphanumeric characters, hyphens and at least one '/' defining a category"); } if (eventType.Length > Constants.Audit.EventTypeLength) { throw new ArgumentException($"Must be max {Constants.Audit.EventTypeLength} chars.", nameof(eventType)); } if (performingIp != null && performingIp.Length > Constants.Audit.IpLength) { throw new ArgumentException($"Must be max {Constants.Audit.EventTypeLength} chars.", nameof(performingIp)); } var entry = new AuditEntry { PerformingUserId = performingUserId, PerformingDetails = perfomingDetails, PerformingIp = performingIp, EventDateUtc = eventDateUtc, AffectedUserId = affectedUserId, AffectedDetails = affectedDetails, EventType = eventType, EventDetails = eventDetails, }; if (_isAvailable.Value == false) { return(entry); } using (var scope = ScopeProvider.CreateCoreScope()) { _auditEntryRepository.Save(entry); scope.Complete(); } return(entry); }
public void Can_Get_Tagged_Entities_For_Tag() { IScopeProvider provider = ScopeProvider; using (ScopeProvider.CreateScope()) { // create data to relate to // We have to create and save a template, otherwise we get an FK violation on contentType. Template template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); ContentType contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); ContentTypeRepository.Save(contentType); Content content1 = ContentBuilder.CreateSimpleContent(contentType); DocumentRepository.Save(content1); Content content2 = ContentBuilder.CreateSimpleContent(contentType); DocumentRepository.Save(content2); MediaType mediaType = MediaTypeBuilder.CreateImageMediaType("image2"); MediaTypeRepository.Save(mediaType); Media media1 = MediaBuilder.CreateMediaImage(mediaType, -1); MediaRepository.Save(media1); TagRepository repository = CreateRepository(provider); Tag[] tags = new[] { new Tag { Text = "tag1", Group = "test" }, new Tag { Text = "tag2", Group = "test1" }, new Tag { Text = "tag3", Group = "test" } }; repository.Assign( content1.Id, contentType.PropertyTypes.First().Id, tags, false); Tag[] tags2 = new[] { new Tag { Text = "tag1", Group = "test" }, new Tag { Text = "tag2", Group = "test1" }, }; repository.Assign( content2.Id, contentType.PropertyTypes.Last().Id, tags2, false); Tag[] tags3 = new[] { new Tag { Text = "tag1", Group = "test" }, new Tag { Text = "tag2", Group = "test1" } }; repository.Assign( media1.Id, mediaType.PropertyTypes.Last().Id, tags3, false); TaggedEntity[] contentTestIds = repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Content, "tag1").ToArray(); // there are two content items tagged against the 'tag1' tag Assert.AreEqual(2, contentTestIds.Length); // there are a total of two property types tagged against the 'tag1' tag Assert.AreEqual(2, contentTestIds.SelectMany(x => x.TaggedProperties).Count()); // there are a total of 1 tags since we're only looking against one tag Assert.AreEqual(1, contentTestIds.SelectMany(x => x.TaggedProperties).SelectMany(x => x.Tags).Select(x => x.Id).Distinct().Count()); TaggedEntity[] contentTest1Ids = repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Content, "tag3").ToArray(); // there are 1 content items tagged against the 'tag3' tag Assert.AreEqual(1, contentTest1Ids.Length); // there are a total of two property types tagged against the 'tag3' tag Assert.AreEqual(1, contentTest1Ids.SelectMany(x => x.TaggedProperties).Count()); // there are a total of 1 tags since we're only looking against one tag Assert.AreEqual(1, contentTest1Ids.SelectMany(x => x.TaggedProperties).SelectMany(x => x.Tags).Select(x => x.Id).Distinct().Count()); IEnumerable <TaggedEntity> mediaTestIds = repository.GetTaggedEntitiesByTag(TaggableObjectTypes.Media, "tag1"); Assert.AreEqual(1, mediaTestIds.Count()); } }
public void Truncate_Insert_Vs_Update_Insert() { var customObjectType = Guid.NewGuid(); //chuck lots of data in the db var nodes = PrimeDbWithLotsOfContentXmlRecords(customObjectType); var proflog = GetTestProfilingLogger(); //now we need to test the difference between truncating all records and re-inserting them as we do now, //vs updating them (which might result in checking if they exist for or listening on an exception). using (proflog.DebugDuration <PerformanceTests>("Starting truncate + normal insert test")) using (var scope = ScopeProvider.CreateScope()) { //do this 10x! for (var i = 0; i < 10; i++) { //clear all the xml entries scope.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN (SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml INNER JOIN cmsContent ON cmsContentXml.nodeId = cmsContent.nodeId)"); //now we insert each record for the ones we've deleted like we do in the content service. var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList(); foreach (var xml in xmlItems) { var result = scope.Database.Insert(xml); } } scope.Complete(); } //now, isntead of truncating, we'll attempt to update and if it doesn't work then we insert using (proflog.DebugDuration <PerformanceTests>("Starting update test")) using (var scope = ScopeProvider.CreateScope()) { //do this 10x! for (var i = 0; i < 10; i++) { //now we insert each record for the ones we've deleted like we do in the content service. var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList(); foreach (var xml in xmlItems) { var result = scope.Database.Update(xml); } } scope.Complete(); } //now, test truncating but then do bulk insertion of records using (proflog.DebugDuration <PerformanceTests>("Starting truncate + bulk insert test")) using (var scope = ScopeProvider.CreateScope()) { //do this 10x! for (var i = 0; i < 10; i++) { //clear all the xml entries scope.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN (SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml INNER JOIN cmsContent ON cmsContentXml.nodeId = cmsContent.nodeId)"); //now we insert each record for the ones we've deleted like we do in the content service. var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList(); scope.Database.BulkInsertRecordsWithTransaction(xmlItems); } } //now, test truncating but then do bulk insertion of records using (proflog.DebugDuration <PerformanceTests>("Starting truncate + bulk insert test in one transaction")) using (var scope = ScopeProvider.CreateScope()) { //do this 10x! for (var i = 0; i < 10; i++) { //now we insert each record for the ones we've deleted like we do in the content service. var xmlItems = nodes.Select(node => new ContentXmlDto { NodeId = node.NodeId, Xml = UpdatedXmlStructure }).ToList(); using (var tr = scope.Database.GetTransaction()) { //clear all the xml entries scope.Database.Execute(@"DELETE FROM cmsContentXml WHERE nodeId IN (SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml INNER JOIN cmsContent ON cmsContentXml.nodeId = cmsContent.nodeId)"); scope.Database.BulkInsertRecords(xmlItems); tr.Complete(); } } } }
public void Can_Get_Tags_For_Entity_Type_For_Group() { IScopeProvider provider = ScopeProvider; using (ScopeProvider.CreateScope()) { // create data to relate to // We have to create and save a template, otherwise we get an FK violation on contentType. Template template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); ContentType contentType = ContentTypeBuilder.CreateSimpleContentType("test", "Test", defaultTemplateId: template.Id); ContentTypeRepository.Save(contentType); Content content1 = ContentBuilder.CreateSimpleContent(contentType); DocumentRepository.Save(content1); MediaType mediaType = MediaTypeBuilder.CreateImageMediaType("image2"); MediaTypeRepository.Save(mediaType); Media media1 = MediaBuilder.CreateMediaImage(mediaType, -1); MediaRepository.Save(media1); TagRepository repository = CreateRepository(provider); Tag[] tags = new[] { new Tag { Text = "tag1", Group = "test" }, new Tag { Text = "tag2", Group = "test1" }, new Tag { Text = "tag3", Group = "test" }, new Tag { Text = "tag4", Group = "test1" } }; repository.Assign( content1.Id, contentType.PropertyTypes.First().Id, tags, false); Tag[] tags2 = new[] { new Tag { Text = "tag1", Group = "test" }, new Tag { Text = "tag2", Group = "test1" } }; repository.Assign( media1.Id, mediaType.PropertyTypes.Last().Id, tags2, false); ITag[] result1 = repository.GetTagsForEntityType(TaggableObjectTypes.Content, "test1").ToArray(); ITag[] result2 = repository.GetTagsForEntityType(TaggableObjectTypes.Media, "test1").ToArray(); Assert.AreEqual(2, result1.Length); Assert.AreEqual(1, result2.Length); } }
private Attempt <IPartialView> CreatePartialViewMacro(IPartialView partialView, PartialViewType partialViewType, string snippetName = null, int userId = Constants.Security.SuperUserId) { string partialViewHeader; switch (partialViewType) { case PartialViewType.PartialView: partialViewHeader = PartialViewHeader; break; case PartialViewType.PartialViewMacro: partialViewHeader = PartialViewMacroHeader; break; default: throw new ArgumentOutOfRangeException(nameof(partialViewType)); } string partialViewContent = null; if (snippetName.IsNullOrWhiteSpace() == false) { //create the file var snippetPathAttempt = TryGetSnippetPath(snippetName); if (snippetPathAttempt.Success == false) { throw new InvalidOperationException("Could not load snippet with name " + snippetName); } using (var snippetFile = new StreamReader(System.IO.File.OpenRead(snippetPathAttempt.Result))) { var snippetContent = snippetFile.ReadToEnd().Trim(); //strip the @inherits if it's there snippetContent = StripPartialViewHeader(snippetContent); //Update Model.Content. to be Model. when used as PartialView if (partialViewType == PartialViewType.PartialView) { snippetContent = snippetContent.Replace("Model.Content.", "Model."); } partialViewContent = $"{partialViewHeader}{Environment.NewLine}{snippetContent}"; } } using (var scope = ScopeProvider.CreateScope()) { var newEventArgs = new NewEventArgs <IPartialView>(partialView, true, partialView.Alias, -1); if (scope.Events.DispatchCancelable(CreatingPartialView, this, newEventArgs)) { scope.Complete(); return(Attempt <IPartialView> .Fail()); } var repository = GetPartialViewRepository(partialViewType); if (partialViewContent != null) { partialView.Content = partialViewContent; } repository.Save(partialView); newEventArgs.CanCancel = false; scope.Events.Dispatch(CreatedPartialView, this, newEventArgs); Audit(AuditType.Save, userId, -1, partialViewType.ToString()); scope.Complete(); } return(Attempt <IPartialView> .Succeed(partialView)); }
/// <summary> /// Sets the /// <see cref="ScopeProvider">ScopeProvider</see> /// that provides a scope to be used /// for script evaluation. /// </summary> public virtual void SetScopeProvider(ScopeProvider p) { dim.SetScopeProvider(p); }
public void ConcurrentWritersTest() { const int threadCount = 8; var threads = new Thread[threadCount]; var exceptions = new Exception[threadCount]; var locker = new object(); var acquired = 0; var entered = 0; var ms = new AutoResetEvent[threadCount]; for (var i = 0; i < threadCount; i++) { ms[i] = new AutoResetEvent(false); } var m1 = new ManualResetEventSlim(false); for (var i = 0; i < threadCount; i++) { var ic = i; // capture threads[i] = new Thread(() => { using (var scope = ScopeProvider.CreateScope()) { try { lock (locker) { entered++; if (entered == threadCount) { m1.Set(); } } ms[ic].WaitOne(); scope.Database.AcquireLockNodeWriteLock(Constants.Locks.Servers); lock (locker) { acquired++; } ms[ic].WaitOne(); lock (locker) { acquired--; } } catch (Exception e) { exceptions[ic] = e; } scope.Complete(); } }); } // safe call context ensures that current scope does not leak into starting threads using (new SafeCallContext()) { foreach (var thread in threads) { thread.Start(); } } m1.Wait(); // all threads have entered ms[0].Set(); // let 0 go Thread.Sleep(100); for (var i = 1; i < threadCount; i++) { ms[i].Set(); // let others go } Thread.Sleep(500); // only 1 thread has locked Assert.AreEqual(1, acquired); for (var i = 0; i < threadCount; i++) { ms[i].Set(); // let all go } foreach (var thread in threads) { thread.Join(); } Assert.AreEqual(0, acquired); for (var i = 0; i < threadCount; i++) { Assert.IsNull(exceptions[i]); } }
public void ConcurrentReadersTest() { const int threadCount = 8; var threads = new Thread[threadCount]; var exceptions = new Exception[threadCount]; var locker = new object(); var acquired = 0; var m2 = new ManualResetEventSlim(false); var m1 = new ManualResetEventSlim(false); for (var i = 0; i < threadCount; i++) { var ic = i; // capture threads[i] = new Thread(() => { using (var scope = ScopeProvider.CreateScope()) { try { scope.Database.AcquireLockNodeReadLock(Constants.Locks.Servers); lock (locker) { acquired++; if (acquired == threadCount) { m2.Set(); } } m1.Wait(); lock (locker) { acquired--; } } catch (Exception e) { exceptions[ic] = e; } scope.Complete(); } }); } // safe call context ensures that current scope does not leak into starting threads using (new SafeCallContext()) { foreach (var thread in threads) { thread.Start(); } } m2.Wait(); // all threads have locked in parallel var maxAcquired = acquired; m1.Set(); foreach (var thread in threads) { thread.Join(); } Assert.AreEqual(threadCount, maxAcquired); Assert.AreEqual(0, acquired); for (var i = 0; i < threadCount; i++) { Assert.IsNull(exceptions[i]); } }
public void PathTests() { // unless noted otherwise, no changes / 7.2.8 using (IScope scope = ScopeProvider.CreateScope()) { IScriptRepository repository = CreateRepository(); IScript script = new Script("test-path-1.js") { Content = "// script" }; repository.Save(script); Assert.IsTrue(_fileSystem.FileExists("test-path-1.js")); Assert.AreEqual("test-path-1.js", script.Path); Assert.AreEqual("/scripts/test-path-1.js", script.VirtualPath); // ensure you can prefix the same path as the root path name script = new Script("scripts/path-2/test-path-2.js") { Content = "// script" }; repository.Save(script); Assert.IsTrue(_fileSystem.FileExists("scripts/path-2/test-path-2.js")); Assert.AreEqual("scripts\\path-2\\test-path-2.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path); Assert.AreEqual("/scripts/scripts/path-2/test-path-2.js", script.VirtualPath); script = new Script("path-2/test-path-2.js") { Content = "// script" }; repository.Save(script); Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-2.js")); Assert.AreEqual("path-2\\test-path-2.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path); // fixed in 7.3 - 7.2.8 does not update the path Assert.AreEqual("/scripts/path-2/test-path-2.js", script.VirtualPath); script = repository.Get("path-2/test-path-2.js"); Assert.IsNotNull(script); Assert.AreEqual("path-2\\test-path-2.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path); Assert.AreEqual("/scripts/path-2/test-path-2.js", script.VirtualPath); script = new Script("path-2\\test-path-3.js") { Content = "// script" }; repository.Save(script); Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-3.js")); Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path); Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath); script = repository.Get("path-2/test-path-3.js"); Assert.IsNotNull(script); Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path); Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath); script = repository.Get("path-2\\test-path-3.js"); Assert.IsNotNull(script); Assert.AreEqual("path-2\\test-path-3.js".Replace("\\", $"{Path.DirectorySeparatorChar}"), script.Path); Assert.AreEqual("/scripts/path-2/test-path-3.js", script.VirtualPath); script = new Script("\\test-path-4.js") { Content = "// script" }; Assert.Throws <UnauthorizedAccessException>(() => // fixed in 7.3 - 7.2.8 used to strip the \ repository.Save(script)); script = repository.Get("missing.js"); Assert.IsNull(script); // fixed in 7.3 - 7.2.8 used to... Assert.Throws <UnauthorizedAccessException>(() => script = repository.Get("\\test-path-4.js")); Assert.Throws <UnauthorizedAccessException>(() => script = repository.Get("../packages.config")); } }
/// <summary>Sets the ScopeProvider to be used.</summary> /// <remarks>Sets the ScopeProvider to be used.</remarks> public virtual void SetScopeProvider(ScopeProvider scopeProvider) { this.scopeProvider = scopeProvider; }
public void PathTests() { // unless noted otherwise, no changes / 7.2.8 using (ScopeProvider.CreateScope()) { IStylesheetRepository repository = CreateRepository(); IStylesheet stylesheet = new Stylesheet("test-path-1.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" }; repository.Save(stylesheet); Assert.IsTrue(_fileSystem.FileExists("test-path-1.css")); Assert.AreEqual("test-path-1.css", stylesheet.Path); Assert.AreEqual("/css/test-path-1.css", stylesheet.VirtualPath); stylesheet = new Stylesheet("path-2/test-path-2.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" }; repository.Save(stylesheet); Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-2.css")); Assert.AreEqual("path-2\\test-path-2.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path); Assert.AreEqual("/css/path-2/test-path-2.css", stylesheet.VirtualPath); stylesheet = repository.Get("path-2/test-path-2.css"); Assert.IsNotNull(stylesheet); Assert.AreEqual("path-2\\test-path-2.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path); Assert.AreEqual("/css/path-2/test-path-2.css", stylesheet.VirtualPath); stylesheet = new Stylesheet("path-2\\test-path-3.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" }; repository.Save(stylesheet); Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-3.css")); Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path); Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath); stylesheet = repository.Get("path-2/test-path-3.css"); Assert.IsNotNull(stylesheet); Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path); Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath); stylesheet = repository.Get("path-2\\test-path-3.css"); Assert.IsNotNull(stylesheet); Assert.AreEqual("path-2\\test-path-3.css".Replace("\\", $"{Path.DirectorySeparatorChar}"), stylesheet.Path); Assert.AreEqual("/css/path-2/test-path-3.css", stylesheet.VirtualPath); stylesheet = new Stylesheet("..\\test-path-4.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" }; Assert.Throws <UnauthorizedAccessException>(() => repository.Save(stylesheet)); stylesheet = new Stylesheet("\\test-path-5.css") { Content = "body { color:#000; } .bold {font-weight:bold;}" }; repository.Save(stylesheet); stylesheet = repository.Get("\\test-path-5.css"); Assert.IsNotNull(stylesheet); Assert.AreEqual("test-path-5.css", stylesheet.Path); Assert.AreEqual("/css/test-path-5.css", stylesheet.VirtualPath); stylesheet = repository.Get("missing.css"); Assert.IsNull(stylesheet); // #7713 changes behaviour to return null when outside the filesystem // to accomodate changing the CSS path and not flooding the backoffice with errors stylesheet = repository.Get("..\\test-path-4.css"); // outside the filesystem, does not exist Assert.IsNull(stylesheet); stylesheet = repository.Get("../packages.config"); // outside the filesystem, exists Assert.IsNull(stylesheet); } }
public override void NormalizeClientModel(ServiceClient client) { if (client == null) { throw new ArgumentNullException("client"); } base.NormalizeClientModel(client); foreach (var method in client.Methods) { //if (method.Group != null) //{ // method.Group = method.Group.ToPythonCase(); //} var scope = new ScopeProvider(); foreach (var parameter in method.Parameters) { if (parameter.ClientProperty != null) { parameter.Name = string.Format(CultureInfo.InvariantCulture, "self.config.{0}", parameter.ClientProperty.Name); } else { parameter.Name = scope.GetVariableName(parameter.Name); } } } }
public void Delete(TItem item, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { var deleteEventArgs = new DeleteEventArgs <TItem>(item); if (OnDeletingCancelled(scope, deleteEventArgs)) { scope.Complete(); return; } scope.WriteLock(WriteLockIds); // all descendants are going to be deleted var descendantsAndSelf = GetDescendants(item.Id, true) .ToArray(); var deleted = descendantsAndSelf; // all impacted (through composition) probably lose some properties // don't try to be too clever here, just report them all // do this before anything is deleted var changed = descendantsAndSelf.SelectMany(xx => GetComposedOf(xx.Id)) .Distinct() .Except(descendantsAndSelf) .ToArray(); // delete content DeleteItemsOfTypes(descendantsAndSelf.Select(x => x.Id)); // Next find all other document types that have a reference to this content type var referenceToAllowedContentTypes = GetAll().Where(q => q.AllowedContentTypes.Any(p => p.Id.Value == item.Id)); foreach (var reference in referenceToAllowedContentTypes) { reference.AllowedContentTypes = reference.AllowedContentTypes.Where(p => p.Id.Value != item.Id); var changedRef = new List <ContentTypeChange <TItem> >() { new ContentTypeChange <TItem>(reference, ContentTypeChangeTypes.RefreshMain) }; // Fire change event OnChanged(scope, changedRef.ToEventArgs()); } // finally delete the content type // - recursively deletes all descendants // - deletes all associated property data // (contents of any descendant type have been deleted but // contents of any composed (impacted) type remain but // need to have their property data cleared) Repository.Delete(item); //... var changes = descendantsAndSelf.Select(x => new ContentTypeChange <TItem>(x, ContentTypeChangeTypes.Remove)) .Concat(changed.Select(x => new ContentTypeChange <TItem>(x, ContentTypeChangeTypes.RefreshMain | ContentTypeChangeTypes.RefreshOther))); var args = changes.ToEventArgs(); OnUowRefreshedEntity(args); OnChanged(scope, args); deleteEventArgs.DeletedEntities = deleted.DistinctBy(x => x.Id); deleteEventArgs.CanCancel = false; OnDeleted(scope, deleteEventArgs); Audit(AuditType.Delete, userId, item.Id); scope.Complete(); } }