public TypedEntityToIndexOperation(AbstractFluentMappingEngine engine) : base(engine) { MappingContext .CreateUsing(x => new NestedHiveIndexOperation()) .ForMember(x => x.Entity, opt => opt.MapFrom(y => y)) .ForMember(x => x.OperationType, opt => opt.MapFrom(y => IndexOperationType.Add)) .ForMember(x => x.Id, opt => opt.MapFrom(y => new Lazy <string>(() => y.Id.Value.ToString()))) .ForMember(x => x.ItemCategory, opt => opt.MapFrom(y => typeof(TypedEntity).Name)) .ForMember(x => x.Fields, opt => opt.MapUsing <TypedEntityToIndexFields>()) .AfterMap((s, t) => { //create sub operations for each of the children //NOTE: we don't store TypedAttribute seperately in the index, they get stored with the TypedEntity! //NOTE: we need to store the entity id in a seperate field to the normal id when using revisions t.AddOrUpdateField(FixedIndexedFields.EntityId, new Lazy <string>(() => s.Id.Value.ToString())); s.MapRelations(t, MappingContext.Engine); t.SubIndexOperations.Add(MappingContext.Engine.Map <EntitySchema, NestedHiveIndexOperation>(s.EntitySchema)); ExamineHelper.SetTimestampsOnEntityAndIndexFields(t.Fields, s); //ensure the IsLatest flag is set, this is only used if we're supporting Revisions. If we change //to a NullRevisionFactory then only one TypedEntity will ever exist. t.Fields.Add(FixedRevisionIndexFields.IsLatest, new ItemField(1) { DataType = FieldDataType.Int }); }); }
public IEnumerable <SimpleDataSet> GetAllData(string indexType) { var config = FileIndexerConfig.Settings; var fullPath = HttpContext.Current.Server.MapPath(config.DirectoryToIndex); var directory = new DirectoryInfo(fullPath); var files = config.Recursive ? directory.GetFiles(config.SupportedFileTypes, SearchOption.AllDirectories) : directory.GetFiles(config.SupportedFileTypes); var dataSets = new List <SimpleDataSet>(); var i = 1; //unique id for each doc foreach (var file in files) { try { var simpleDataSet = new SimpleDataSet { NodeDefinition = new IndexedNode(), RowData = new Dictionary <string, string>() }; simpleDataSet = ExamineHelper.MapFileToSimpleDataIndexItem(file, simpleDataSet, i, indexType); dataSets.Add(simpleDataSet); } catch (Exception ex) { Log.Add(LogTypes.Error, i, "error processing file " + file.FullName + " " + ex); } i++; } return(dataSets); }
public override IEnumerable <T> PerformExecuteMany <T>(QueryDescription query, ObjectBinder objectBinder) { var direction = query.From.HierarchyScope; var criteria = new ExamineQueryVisitor(Helper.ExamineManager).Visit(query.Criteria); // Include revision status in query var revisionCriteria = Helper.ExamineManager.CreateSearchCriteria(); revisionCriteria.Must().Field(FixedRevisionIndexFields.RevisionStatusAlias, query.From.RevisionStatus); IQuery finalQuery = null; // Only include the revision status if it was included in the query if (query.From.RevisionStatus != FromClause.RevisionStatusNotSpecified) { finalQuery = (criteria.ToString() == "") ? revisionCriteria.Compile() : ((LuceneSearchCriteria)criteria).Join((LuceneSearchCriteria)revisionCriteria.Compile(), BooleanClause.Occur.MUST);; } else { finalQuery = criteria; } IEnumerable <SearchResult> results = Helper.ExamineManager.Search(finalQuery); // Now apply an in-memory filter to account for some of the shortcomings of Lucene (e.g. no MAX support) var detailedResults = results.Select(x => new { EntityId = HiveId.Parse(x.Fields.GetValue(FixedIndexedFields.EntityId, HiveId.Empty.ToString())), RevisionId = HiveId.Parse(x.Fields.GetValue(FixedRevisionIndexFields.RevisionId, HiveId.Empty.ToString())), UtcStatusChanged = ExamineHelper.FromExamineDateTime(x.Fields, FixedIndexedFields.UtcStatusChanged), Result = x }).ToArray(); IEnumerable <SearchResult> maxByDate = detailedResults.GroupBy(x => x.EntityId, (key, matches) => matches.OrderByDescending(x => x.UtcStatusChanged).FirstOrDefault()) .Select(x => x.Result) .ToArray(); switch (query.ResultFilter.ResultFilterType) { case ResultFilterType.Any: return(new[] { maxByDate.Count() != 0 }.Cast <T>()); case ResultFilterType.Count: //this is weird but returns an integer return(new[] { maxByDate.Count() }.Cast <T>()); case ResultFilterType.Take: maxByDate = maxByDate.Take(query.ResultFilter.SelectorArgument); break; } if (typeof(T).IsAssignableFrom(query.ResultFilter.ResultType)) { return(maxByDate.Distinct().Select(node => FrameworkContext.TypeMappers.Map <T>(node))); } return(Enumerable.Empty <T>()); }
/// <summary> /// Internal constructor for testing /// </summary> /// <param name="providerMetadata"></param> /// <param name="frameworkContext"></param> /// <param name="helper"></param> internal RevisionRepositoryFactory( ProviderMetadata providerMetadata, IFrameworkContext frameworkContext, ExamineHelper helper) : base(providerMetadata, frameworkContext, new DependencyHelper(helper, providerMetadata)) { }
public void From_AttributeDefinition_To_IndexOperation() { //Arrange var entity = CreateTypedEntity(); var attDef = entity.EntitySchema.AttributeDefinitions.First(); //Act var result = _mapper.Map <AttributeDefinition, NestedHiveIndexOperation>(attDef); //lazily add the ids ExamineHelper.EnsureIds(result); //Assert Assert.AreEqual("AttributeDefinition", result.ItemCategory); Assert.AreEqual(IndexOperationType.Add, result.OperationType); Assert.AreEqual(attDef.Id.Value.ToString(), result.Id.Value); Assert.AreEqual(attDef.Alias, result.Fields["Alias"].FieldValue); Assert.AreEqual(attDef.Name, result.Fields["Name"].FieldValue); Assert.AreEqual(attDef.Description, result.Fields["Description"].FieldValue); Assert.AreEqual(attDef.Ordinal, result.Fields["Ordinal"].FieldValue); Assert.IsNotNull(result.Fields[FixedIndexedFields.GroupId].FieldValue); Assert.AreEqual(attDef.AttributeGroup.Id.Value, result.Fields[FixedIndexedFields.GroupId].FieldValue); Assert.IsNotNull(result.Fields[FixedIndexedFields.AttributeTypeId].FieldValue); Assert.AreEqual(attDef.AttributeType.Id.Value, result.Fields[FixedIndexedFields.AttributeTypeId].FieldValue); //NOTE: Groups is not a sub operation because a group is attached to a schema, not definition Assert.AreEqual(1, result.SubIndexOperations.Count); VerifyIEntityFields(result, attDef); }
/// <summary> /// Constructor used for testing /// </summary> /// <param name="providerMetadata"></param> /// <param name="revisionRepositoryFactory"></param> /// <param name="frameworkContext"></param> /// <param name="helper"></param> internal SchemaRepositoryFactory( ProviderMetadata providerMetadata, AbstractRevisionRepositoryFactory <EntitySchema> revisionRepositoryFactory, IFrameworkContext frameworkContext, ExamineHelper helper) : base(providerMetadata, revisionRepositoryFactory, frameworkContext, new DependencyHelper(helper, providerMetadata)) { }
/// <summary> /// Constructor used for testing /// </summary> /// <param name="providerMetadata"></param> /// <param name="revisionRepositoryFactory"></param> /// <param name="frameworkContext"></param> /// <param name="helper"></param> internal SchemaRepositoryFactory( ProviderMetadata providerMetadata, AbstractRevisionRepositoryFactory<EntitySchema> revisionRepositoryFactory, IFrameworkContext frameworkContext, ExamineHelper helper) : base(providerMetadata, revisionRepositoryFactory, frameworkContext, new DependencyHelper(helper, providerMetadata)) { }
public ExamineTestSetupHelper(FakeFrameworkContext frameworkContext = null, bool isPassthrough = false) { var examineWorkingFolder = new DirectoryInfo(Path.Combine(Common.CurrentAssemblyDirectory, "Examine", Guid.NewGuid().ToString() + Thread.CurrentThread.ManagedThreadId)); if (!examineWorkingFolder.Exists) Directory.CreateDirectory(examineWorkingFolder.FullName); //clear out old folders var parentFolder = examineWorkingFolder.Parent; foreach(var f in parentFolder.GetDirectories().Where(x => x.CreationTimeUtc < DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(5)))) { try { Directory.Delete(f.FullName, true); } catch (IOException) { //ignore } } LogHelper.TraceIfEnabled<ExamineTestSetupHelper>("Index setup in folder {0}", () => examineWorkingFolder.FullName); //var disk = new Lucene.Net.Store.RAMDirectory(); var disk = new Lucene.Net.Store.SimpleFSDirectory(examineWorkingFolder); Indexer = new RebelExamineIndexer( new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), SynchronizationType.Synchronized, disk); _fakeFrameworkContext = frameworkContext ?? new FakeFrameworkContext(); Searcher = new LuceneSearcher(new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), disk); ExamineManager = new ExamineManager(new[] { Searcher }, new[] { Indexer }, Searcher); ExamineHelper = new ExamineHelper(ExamineManager, _fakeFrameworkContext, false); //false to not use cache var examineMapper = new ExamineModelMapper(ExamineHelper, _fakeFrameworkContext); _fakeFrameworkContext.SetTypeMappers(new FakeTypeMapperCollection(new AbstractMappingEngine[] { examineMapper, new FrameworkModelMapper(_fakeFrameworkContext) })); var providerMetadata = new ProviderMetadata("r-examine-unit-tester", new Uri("tester://"), true, isPassthrough); var revisionSchemaSessionFactory = new NullProviderRevisionRepositoryFactory<EntitySchema>(providerMetadata, FrameworkContext); var revisionRepositoryFactory = new RevisionRepositoryFactory(providerMetadata, FrameworkContext, ExamineHelper); //var revisionRepositoryFactory = new NullProviderRevisionSessionFactory<TypedEntity>(providerMetadata, FrameworkContext); var schemaRepositoryFactory = new SchemaRepositoryFactory(providerMetadata, revisionSchemaSessionFactory, FrameworkContext, ExamineHelper); var entityRepositoryFactory = new EntityRepositoryFactory(providerMetadata, revisionRepositoryFactory, schemaRepositoryFactory, FrameworkContext, ExamineHelper); var readUnitFactory = new ReadonlyProviderUnitFactory(entityRepositoryFactory); var unitFactory = new ProviderUnitFactory(entityRepositoryFactory); ProviderSetup = new ProviderSetup(unitFactory, providerMetadata, FrameworkContext, null, 0); ReadonlyProviderSetup = new ReadonlyProviderSetup(readUnitFactory, providerMetadata, FrameworkContext, null, 0); //ensure that the index exists Indexer.CreateIndex(true); }
public RevisionRepository( ProviderMetadata providerMetadata, IProviderTransaction providerTransaction, IFrameworkContext frameworkContext, ExamineHelper helper) : base(providerMetadata, providerTransaction, frameworkContext) { Helper = helper; ExamineTransaction = providerTransaction as ExamineTransaction; }
public EntityRepository( ProviderMetadata providerMetadata, IProviderTransaction providerTransaction, IFrameworkContext frameworkContext, AbstractRevisionRepository <TypedEntity> revisionRepository, AbstractSchemaRepository schemaSession, ExamineHelper helper) : base(providerMetadata, providerTransaction, revisionRepository, schemaSession, frameworkContext) { Helper = helper; ExamineTransaction = providerTransaction as ExamineTransaction; Mandate.That(ExamineTransaction != null, x => new InvalidCastException("The IProviderTransaction for the Examine EntityRepository must be of Type ExamineTransaction")); }
public override LazyDictionary <string, ItemField> GetValue(TypedEntity source) { var d = new LazyDictionary <string, ItemField>(); foreach (var a in source.Attributes) { if (a.Values.Count == 1) { StoreFieldValue(a.AttributeDefinition.AttributeType.SerializationType, FixedAttributeIndexFields.AttributePrefix + a.AttributeDefinition.Alias, a.DynamicValue, d); } else if (a.Values.Count > 1) { //we need to put multiple values in the index with dot notation foreach (var val in a.Values) { var key = FixedAttributeIndexFields.AttributePrefix + a.AttributeDefinition.Alias + "." + val.Key; StoreFieldValue(a.AttributeDefinition.AttributeType.SerializationType, key, val.Value, d); } } //put attribute alias/name/id in there FixedAttributeIndexFields.AddAttributeAlias(d, a); //FixedAttributeIndexFields.AddAttributeName(d, a); FixedAttributeIndexFields.AddAttributeId(d, a); } //Get the parent Id. //TODO: We should support all relation types in some magical way foreach (var r in source.RelationProxies.GetParentRelations(FixedRelationTypes.DefaultRelationType)) { d.AddOrUpdate(FixedIndexedFields.ParentId, new ItemField(r.Item.SourceId.Value.ToString())); } d.AddOrUpdate(FixedIndexedFields.SchemaId, new Lazy <ItemField>(() => new ItemField(source.EntitySchema.Id.Value.ToString())), (k, i) => new Lazy <ItemField>(() => new ItemField(source.EntitySchema.Id.Value.ToString()))); d.Add(FixedIndexedFields.SchemaAlias, new ItemField(source.EntitySchema.Alias)); d.AddOrUpdate(FixedIndexedFields.SchemaName, new ItemField(source.EntitySchema.Name)); d.AddOrUpdate(FixedIndexedFields.SchemaType, new ItemField(source.EntitySchema.SchemaType)); ExamineHelper.SetTimestampsOnEntityAndIndexFields(d, source); return(d); }
public override LazyDictionary <string, ItemField> GetValue(AttributeType source) { ////TODO: This is purely a hack in order to get the installer working with Examine, its also a required hack until the underlying //// issue is fixed: Currently we need to make sure that the properties of an Attribute type remain constant in the repository unless //// that property is explicitly changed. This is mostly to do with the RenderTypeProvider property as we don't want it to be overwritten //// with a empty value when a system attribute type is committed. //if (!source.Id.IsNullValueOrEmpty()) //{ // var existing = _helper.PerformGet<AttributeType>(true, LuceneIndexer.IndexNodeIdFieldName, source.Id); // var destination = existing.LastOrDefault(); // if (destination != null) // { // //This copies across all changed (Dirty) properties from the source to the destination except for a few of the properties // destination.SetAllChangedProperties<AttributeType, object>(source, // x => x.Id, // x => x.ConcurrencyToken, // x => x.PersistenceMetadata, // x => x.UtcCreated, // x => x.UtcModified, // x => x.UtcStatusChanged); // //now that all properties are updated that have changed, overwrite the 'source' object with the destination so it can be mapped // //to the index fields properly to be stored. // source = destination; // } //} //convert the source to a dictionary object ignoring some of its properties var d = source.ToDictionary <AttributeType, object, object>( x => x.Id, x => x.SerializationType, x => x.ConcurrencyToken); //add the serialization FQN so we can re-create it later d.Add(FixedIndexedFields.SerializationType, source.SerializationType.GetType().FullName); var output = new LazyDictionary <string, ItemField>(); foreach (var i in d) { output.Add(i.Key, new ItemField(i.Value)); } ExamineHelper.SetTimestampsOnEntityAndIndexFields(output, source); return(output); }
public void From_EntitySchema_To_IndexOperation() { //Arrange var input = HiveModelCreationHelper.CreateEntitySchema("test" + Guid.NewGuid(), "Test" + Guid.NewGuid(), true, HiveModelCreationHelper.CreateAttributeDefinition("test" + Guid.NewGuid(), "Test" + Guid.NewGuid(), "this is a test" + Guid.NewGuid(), HiveModelCreationHelper.CreateAttributeType("test" + Guid.NewGuid(), "Test" + Guid.NewGuid(), "this is a test" + Guid.NewGuid()), HiveModelCreationHelper.CreateAttributeGroup("test" + Guid.NewGuid(), "Test" + Guid.NewGuid(), new Random().Next(0, 1000), true), true)); var child = HiveModelCreationHelper.CreateEntitySchema("test" + Guid.NewGuid(), "Test" + Guid.NewGuid(), true, HiveModelCreationHelper.CreateAttributeDefinition("test" + Guid.NewGuid(), "Test" + Guid.NewGuid(), "this is a test" + Guid.NewGuid(), HiveModelCreationHelper.CreateAttributeType("test" + Guid.NewGuid(), "Test" + Guid.NewGuid(), "this is a test" + Guid.NewGuid()), HiveModelCreationHelper.CreateAttributeGroup("test" + Guid.NewGuid(), "Test" + Guid.NewGuid(), new Random().Next(0, 1000), true), true)); input.RelationProxies.EnlistChild(child, FixedRelationTypes.DefaultRelationType); //Act var output = _mapper.Map <EntitySchema, NestedHiveIndexOperation>(input); //lazily add the ids ExamineHelper.EnsureIds(output); //Assert Assert.AreEqual(typeof(EntitySchema).Name, output.ItemCategory); Assert.AreEqual(IndexOperationType.Add, output.OperationType); Assert.AreEqual(input.Id.Value.ToString(), output.Id.Value); Assert.AreEqual(input.SchemaType, output.Fields["SchemaType"].FieldValue); Assert.AreEqual( input.AttributeDefinitions.Count() + input.AttributeGroups.Count() + input.RelationProxies.AllChildRelations().Count() + 1, output.SubIndexOperations.Count()); Assert.AreEqual(input, output.Entity); var fieldMapper = new EntitySchemaToIndexFields(); Assert.AreEqual(fieldMapper.GetValue(input).Count(), output.Fields.Count()); VerifyIEntityFields(output, input); foreach (var a in output.SubIndexOperations.Where(x => x.Entity is AttributeDefinition).ToArray()) { Assert.IsFalse(((HiveIdValue)a.Fields[FixedIndexedFields.GroupId].FieldValue) == HiveIdValue.Empty); } }
public override LazyDictionary <string, ItemField> GetValue(AttributeGroup source) { //convert the source to a dictionary object ignoring some of its properties var d = source.ToDictionary <AttributeGroup, object, object>( x => x.Id, x => x.ConcurrencyToken); var output = new LazyDictionary <string, ItemField>(); foreach (var i in d) { output.Add(i.Key, new ItemField(i.Value)); } ExamineHelper.SetTimestampsOnEntityAndIndexFields(output, source); return(output); }
/// <summary> /// Adds an index operation to the Queue, if the item already exists it is ignored. /// </summary> /// <param name="op"></param> public void EnqueueIndexOperation(LinearHiveIndexOperation op) { if (!_itemsToIndex.ShouldAddNewQueueItem(op)) { return; } //before we process each item, we need to update all of the item ids if they haven't been set if (op.OperationType == IndexOperationType.Add && op.Entity != null) { //check if we should be creating Ids if (!_providerMetadata.IsPassthroughProvider) { ExamineHelper.EnsureIds(op); } } _itemsToIndex.Add(op); }
private dynamic GetRealValueFromField(IAttributeSerializationDefinition serializationDefinition, string savedVal) { switch (serializationDefinition.DataSerializationType) { case DataSerializationTypes.Guid: case DataSerializationTypes.String: case DataSerializationTypes.LongString: case DataSerializationTypes.Boolean: return(savedVal); case DataSerializationTypes.SmallInt: case DataSerializationTypes.LargeInt: int intOut; if (int.TryParse(savedVal, out intOut)) { return(intOut); } throw new InvalidCastException("Could not parse value " + savedVal + " into an int Type"); case DataSerializationTypes.Decimal: decimal decOut; if (decimal.TryParse(savedVal, out decOut)) { return(decOut); } throw new InvalidCastException("Could not parse value " + savedVal + " into an decimal Type"); case DataSerializationTypes.Date: var dateTime = ExamineHelper.FromExamineDateTime(savedVal); if (dateTime != null) { return(dateTime); } throw new InvalidCastException("Could not parse value " + savedVal + " into an DateTimeOffset Type"); case DataSerializationTypes.ByteArray: throw new NotImplementedException(); default: throw new ArgumentOutOfRangeException(); } }
public override RevisionData GetValue(SearchResult source) { var id = HiveId.Parse(source.Fields[FixedRevisionIndexFields.RevisionId]); var revStatusId = Guid.Parse(source.Fields[FixedRevisionIndexFields.RevisionStatusId]); var revStatus = _helper.GetRevisionStatusType(revStatusId); if (revStatus == null) { throw new NotSupportedException("Could not find a revision status with status id: " + revStatusId.ToString("N")); } //NOTE: all dates on a revision will be the same correct? since they only exist one time. SD. return(new RevisionData(id, revStatus) { UtcCreated = ExamineHelper.FromExamineDateTime(source.Fields, FixedIndexedFields.UtcModified).Value, UtcModified = ExamineHelper.FromExamineDateTime(source.Fields, FixedIndexedFields.UtcModified).Value, UtcStatusChanged = ExamineHelper.FromExamineDateTime(source.Fields, FixedIndexedFields.UtcModified).Value }); }
/// <summary> /// When the Entity is a Revision, this checks the previous revisions committed during this transaction to see if the status has actually changed, /// if it determines that no previous entry exists in memory for this transaction, it will look up the entity in the index to see if the /// status has changed. It then sets the status changed date accordingly on the TypedEntity and in the index fields. /// </summary> /// <param name="op"></param> /// <param name="revisionsCommitted"></param> /// <returns>Returns a Tuple of the updated TypedEntity and RevisionData</returns> private Tuple <TypedEntity, RevisionData> EnsureCorrectStatusChangedDate(LinearHiveIndexOperation op, IEnumerable <Tuple <TypedEntity, RevisionData> > revisionsCommitted) { dynamic r = op.Entity; TypedEntity te = r.Item; RevisionData rd = r.MetaData; //find all previous TypedEntities in the committed list matching this one var previous = revisionsCommitted.Where(x => x.Item1.Id.Value.ToString() == te.Id.Value.ToString()) .OrderBy(x => x.Item1.UtcModified) .LastOrDefault(); SearchResult latestEntry = GetLatestEntry(r); if (previous == null && latestEntry != null && latestEntry.Fields.ContainsKey(FixedRevisionIndexFields.RevisionStatusId) && latestEntry.Fields[FixedRevisionIndexFields.RevisionStatusId] != rd.StatusType.Id.Value.ToString()) { //if there's nothing in memory but there's a previously saved entry with a different status id, then update the date te.UtcStatusChanged = rd.UtcCreated; op.Fields[FixedIndexedFields.UtcStatusChanged] = new ItemField(te.UtcStatusChanged.UtcDateTime) { DataType = FieldDataType.DateTime }; } else if (previous != null && previous.Item2.StatusType.Id.Value.ToString() != rd.StatusType.Id.Value.ToString()) { //its changed in memory so update the date te.UtcStatusChanged = rd.UtcCreated; op.Fields[FixedIndexedFields.UtcStatusChanged] = new ItemField(te.UtcStatusChanged.UtcDateTime) { DataType = FieldDataType.DateTime }; } else if (latestEntry != null) { //the status hasn't changed and the entity is not new, set to latest entries status changed te.UtcStatusChanged = ExamineHelper.FromExamineDateTime(latestEntry.Fields, FixedIndexedFields.UtcStatusChanged).Value; op.Fields[FixedIndexedFields.UtcStatusChanged] = new ItemField(te.UtcStatusChanged.UtcDateTime) { DataType = FieldDataType.DateTime }; } return(new Tuple <TypedEntity, RevisionData>(te, rd)); }
public override LazyDictionary <string, ItemField> GetValue(AttributeDefinition source) { //convert the source to a dictionary object ignoring some of its properties var d = source.ToDictionary <AttributeDefinition, object, object>( x => x.Id, x => x.AttributeGroup, x => x.AttributeType, x => x.ConcurrencyToken); var output = new LazyDictionary <string, ItemField>(); foreach (var i in d) { output.Add(i.Key, new ItemField(i.Value)); } ExamineHelper.SetTimestampsOnEntityAndIndexFields(output, source); //add some lazy delegates for the ids of the group/attribute type output.Add(FixedIndexedFields.GroupId, new Lazy <ItemField>(() => new ItemField(source.AttributeGroup.Id.Value))); output.Add(FixedIndexedFields.AttributeTypeId, new Lazy <ItemField>(() => new ItemField(source.AttributeType.Id.Value))); return(output); }
public ExamineTestSetupHelper(FakeFrameworkContext frameworkContext = null, bool isPassthrough = false) { var examineWorkingFolder = new DirectoryInfo(Path.Combine(Common.CurrentAssemblyDirectory, "Examine", Guid.NewGuid().ToString() + Thread.CurrentThread.ManagedThreadId)); if (!examineWorkingFolder.Exists) { Directory.CreateDirectory(examineWorkingFolder.FullName); } //clear out old folders var parentFolder = examineWorkingFolder.Parent; foreach (var f in parentFolder.GetDirectories().Where(x => x.CreationTimeUtc < DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(5)))) { try { Directory.Delete(f.FullName, true); } catch (IOException) { //ignore } } LogHelper.TraceIfEnabled <ExamineTestSetupHelper>("Index setup in folder {0}", () => examineWorkingFolder.FullName); //var disk = new Lucene.Net.Store.RAMDirectory(); var disk = new Lucene.Net.Store.SimpleFSDirectory(examineWorkingFolder); Indexer = new UmbracoExamineIndexer( new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), SynchronizationType.Synchronized, disk); _fakeFrameworkContext = frameworkContext ?? new FakeFrameworkContext(); Searcher = new LuceneSearcher(new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), disk); ExamineManager = new ExamineManager(new[] { Searcher }, new[] { Indexer }, Searcher); ExamineHelper = new ExamineHelper(ExamineManager, _fakeFrameworkContext, false); //false to not use cache var examineMapper = new ExamineModelMapper(ExamineHelper, _fakeFrameworkContext); _fakeFrameworkContext.SetTypeMappers(new FakeTypeMapperCollection(new AbstractMappingEngine[] { examineMapper, new FrameworkModelMapper(_fakeFrameworkContext) })); var providerMetadata = new ProviderMetadata("r-examine-unit-tester", new Uri("tester://"), true, isPassthrough); var revisionSchemaSessionFactory = new NullProviderRevisionRepositoryFactory <EntitySchema>(providerMetadata, FrameworkContext); var revisionRepositoryFactory = new RevisionRepositoryFactory(providerMetadata, FrameworkContext, ExamineHelper); //var revisionRepositoryFactory = new NullProviderRevisionSessionFactory<TypedEntity>(providerMetadata, FrameworkContext); var schemaRepositoryFactory = new SchemaRepositoryFactory(providerMetadata, revisionSchemaSessionFactory, FrameworkContext, ExamineHelper); var entityRepositoryFactory = new EntityRepositoryFactory(providerMetadata, revisionRepositoryFactory, schemaRepositoryFactory, FrameworkContext, ExamineHelper); var readUnitFactory = new ReadonlyProviderUnitFactory(entityRepositoryFactory); var unitFactory = new ProviderUnitFactory(entityRepositoryFactory); ProviderSetup = new ProviderSetup(unitFactory, providerMetadata, FrameworkContext, null, 0); ReadonlyProviderSetup = new ReadonlyProviderSetup(readUnitFactory, providerMetadata, FrameworkContext, null, 0); //ensure that the index exists Indexer.CreateIndex(true); }
public ExamineModelMapper(ExamineHelper helper, IFrameworkContext frameworkContext) : base(frameworkContext) { _helper = helper; }
public DependencyHelper(ExamineHelper helper, ProviderMetadata providerMetadata) : base(providerMetadata) { ExamineHelper = helper; }
public ExamineModelMapper(ExamineHelper helper, IFrameworkContext frameworkContext) : base(frameworkContext) { _helper = helper; }
public override void ConfigureMappings() { #region LinearHiveIndexOperation -> IndexOperation this.CreateMap <LinearHiveIndexOperation, IndexOperation>(true) .CreateUsing(x => new IndexOperation()) .MapMemberFrom(x => x.Item, x => new IndexItem { Fields = x.Fields, Id = x.Id.Value, ItemCategory = x.ItemCategory }) .MapMemberFrom(x => x.Operation, x => x.OperationType); #endregion #region SearchResult -> Relation Func <string, int> getOrdinal = (s) => { //need to safe parse the ordinal int ordinal; return(int.TryParse(s, out ordinal) ? ordinal : 0); }; this.CreateMap <SearchResult, IRelationById>() .CreateUsing(x => new RelationById( new HiveId(x.Fields[FixedRelationIndexFields.SourceId]), new HiveId(x.Fields[FixedRelationIndexFields.DestinationId]), new RelationType(x.Fields[FixedRelationIndexFields.RelationType]), getOrdinal(x.Fields[FixedIndexedFields.Ordinal]))) .AfterMap((s, t) => { //need to setup the metadata foreach (var m in s.Fields.Where(x => x.Key.StartsWith(FixedRelationIndexFields.MetadatumPrefix))) { t.MetaData.Add(new RelationMetaDatum(m.Key.Split('.')[1], m.Value)); } }); #endregion #region SearchResult -> Revision<TypedEntity> this.CreateMap <SearchResult, Revision <TypedEntity> >(true) .CreateUsing(x => new Revision <TypedEntity>()) .ForMember(x => x.MetaData, x => x.MapUsing(new SearchResultToRevisionData(_helper))) .MapMemberFrom(x => x.Item, Map <SearchResult, TypedEntity>) .AfterMap((s, t) => { }); #endregion #region SearchResult -> TypedEntity this.CreateMap(new SearchResultToTypedEntity(_helper, this), true) .CreateUsing(x => new TypedEntity()) .ForMember(x => x.Id, opt => opt.MapFrom(y => HiveId.Parse(y.Fields[FixedIndexedFields.EntityId]))) .AfterMap((s, t) => { ExamineHelper.SetEntityDatesFromSearchResult(t, s); }); #endregion #region SearchResult -> EntitySchema this.CreateMap <SearchResult, EntitySchema>() .CreateUsing(x => new EntitySchema()) .ForMember(x => x.Id, opt => opt.MapFrom(y => HiveId.Parse(y.Id))) .ForMember(x => x.Alias, opt => opt.MapFrom(y => y.Fields.GetValueAsString("Alias"))) .ForMember(x => x.Name, opt => opt.MapFrom(y => new LocalizedString(y.Fields.GetValueAsString("Name")))) .ForMember(x => x.SchemaType, opt => opt.MapFrom(y => y.Fields.GetValueAsString("SchemaType"))) .MapMemberFrom(x => x.XmlConfiguration, y => y.Fields.GetValueAsString("XmlConfiguration").IsNullOrWhiteSpace() ? new XDocument() : XDocument.Parse(y.Fields.GetValueAsString("XmlConfiguration"))) .AfterMap((s, t) => { var groups = _helper.GetMappedGroupsForSchema(t.Id); foreach (var g in groups) { t.AttributeGroups.Add(g.Item1); } //find all attribute definitions with this schema id var attDefs = _helper.GetAttributeDefinitionsForSchema(t.Id); //declare a local cache for found attribute types, see notes below. var attributeTypeCache = new List <AttributeType>(); foreach (var a in attDefs) { //ok, we've already looked up the groups and its very IMPORTANT that the same group object is applied //to the AttributeDefinition otherwise problems will occur. //So instead of re-coding the mapping operation for SearchResult -> AttributeDefinition, we'll re-use our //current Map, but we'll ensure that it does not go re-lookup the AttributeGroup. We can do this by removing //the FixedIndexFieldsGroupId item from the fields so it won't think it has a gruop, then we will add the group back. //NOTE: this procedure can be avoided when the ScopedCache is turned on in the ExamineHelper, however // i don't feel that relying on that mechanism is robust. Once we implement an ExamineDataContext to do // the lookup caching instead, then this could be removed. var groupId = a.Fields.ContainsKey(FixedIndexedFields.GroupId) ? a.Fields[FixedIndexedFields.GroupId] : null; a.Fields.Remove(FixedIndexedFields.GroupId); //similar to the above, it is very IMPORTANT that the same AttributeType object is applied to each //of the AttributeDefinitions if they reference the same alias/id. In order to acheive this we will //remove the FixedIndexedFields.AttributeTypeId from the fields so the mapping operation thinks that it //doesn't have one assigned and won't go look it up. We will store the AttributeTypeId locally and look //it up manually and create a local cache to re-assign to the AttributeDefinitions. //NOTE: this procedure can be avoided when the ScopedCache is turned on in the ExamineHelper, however // i don't feel that relying on that mechanism is robust. Once we implement an ExamineDataContext to do // the lookup caching instead, then this could be removed. var attributeTypeId = a.Fields.ContainsKey(FixedIndexedFields.AttributeTypeId) ? a.Fields[FixedIndexedFields.AttributeTypeId] : null; a.Fields.Remove(FixedIndexedFields.AttributeTypeId); //now do the mapping var mappedAttributeDefinition = Map <SearchResult, AttributeDefinition>(a); //now see if we can find the already found group by id if (groupId != null) { var group = t.AttributeGroups.SingleOrDefault(x => x.Id.Value.ToString() == groupId); mappedAttributeDefinition.AttributeGroup = group; } //now see if we can find an attribute type from our cache or from the helper if (attributeTypeId != null) { var attType = attributeTypeCache.SingleOrDefault(x => x.Id.Value.ToString() == attributeTypeId); if (attType == null) { //its not in our cache so look it up and add to cache attType = _helper.PerformGet <AttributeType>(true, LuceneIndexer.IndexNodeIdFieldName, new HiveId(attributeTypeId)) .SingleOrDefault(); if (attType != null) { attributeTypeCache.Add(attType); } } mappedAttributeDefinition.AttributeType = attType; } //add the attribute definition t.AttributeDefinitions.Add(mappedAttributeDefinition); } ExamineHelper.SetEntityDatesFromSearchResult(t, s); }); #endregion #region SearchResult -> AttributeDefinition this.CreateMap <SearchResult, AttributeDefinition>() .CreateUsing(x => new AttributeDefinition()) .ForMember(x => x.Id, opt => opt.MapFrom(y => HiveId.Parse(y.Id))) .ForMember(x => x.Alias, opt => opt.MapFrom(y => y.Fields.GetValueAsString("Alias"))) .ForMember(x => x.Name, opt => opt.MapFrom(y => new LocalizedString(y.Fields.GetValueAsString("Name")))) .ForMember(x => x.Description, opt => opt.MapFrom(y => new LocalizedString(y.Fields.GetValueAsString("Description")))) .ForMember(x => x.RenderTypeProviderConfigOverride, opt => opt.MapFrom(y => y.Fields.GetValueAsString("RenderTypeProviderConfigOverride"))) .AfterMap((s, t) => { //need to do Ordinal safely int ordinal; if (int.TryParse(s.Fields.GetValueAsString(FixedIndexedFields.Ordinal), out ordinal)) { t.Ordinal = ordinal; } //lookup the attribute def & group from hive for the attribute def if (s.Fields.ContainsKey(FixedIndexedFields.GroupId)) { var group = _helper.PerformGet <AttributeGroup>(true, LuceneIndexer.IndexNodeIdFieldName, new HiveId(s.Fields[FixedIndexedFields.GroupId])); t.AttributeGroup = group.SingleOrDefault(); } if (s.Fields.ContainsKey(FixedIndexedFields.AttributeTypeId)) { var attType = _helper.PerformGet <AttributeType>(true, LuceneIndexer.IndexNodeIdFieldName, new HiveId(s.Fields[FixedIndexedFields.AttributeTypeId])); t.AttributeType = attType.SingleOrDefault(); } ExamineHelper.SetEntityDatesFromSearchResult(t, s); }); #endregion #region SearchResult -> AttributeGroup this.CreateMap <SearchResult, AttributeGroup>() .CreateUsing(x => new AttributeGroup()) .ForMember(x => x.Id, opt => opt.MapFrom(y => HiveId.Parse(y.Id))) .ForMember(x => x.Alias, opt => opt.MapFrom(y => y.Fields.GetValueAsString("Alias"))) .ForMember(x => x.Name, opt => opt.MapFrom(y => new LocalizedString(y.Fields.GetValueAsString("Name")))) .AfterMap((s, t) => { //need to do Ordinal safely int ordinal; if (int.TryParse(s.Fields.GetValueAsString(FixedIndexedFields.Ordinal), out ordinal)) { t.Ordinal = ordinal; } ExamineHelper.SetEntityDatesFromSearchResult(t, s); }); #endregion #region SearchResult -> AttributeType this.CreateMap <SearchResult, AttributeType>() .CreateUsing(x => new AttributeType()) .ForMember(x => x.Id, opt => opt.MapFrom(y => HiveId.Parse(y.Id))) .ForMember(x => x.Alias, opt => opt.MapFrom(y => y.Fields.GetValueAsString("Alias"))) .ForMember(x => x.Name, opt => opt.MapFrom(y => new LocalizedString(y.Fields.GetValueAsString("Name")))) .ForMember(x => x.Description, opt => opt.MapFrom(y => new LocalizedString(y.Fields.GetValueAsString("Description")))) .ForMember(x => x.RenderTypeProvider, opt => opt.MapFrom(y => y.Fields.GetValueAsString("RenderTypeProvider"))) .ForMember(x => x.RenderTypeProviderConfig, opt => opt.MapFrom(y => y.Fields.GetValueAsString("RenderTypeProviderConfig"))) .AfterMap((s, t) => { //need to do Ordinal safely int ordinal; if (int.TryParse(s.Fields.GetValueAsString(FixedIndexedFields.Ordinal), out ordinal)) { t.Ordinal = ordinal; } //create the serialization type based on the FQN stored in the index var serializationType = Type.GetType(s.Fields[FixedIndexedFields.SerializationType]); if (serializationType == null) { //this shouldn't happen but in case something has changed in the index, then we'll default to string t.SerializationType = new StringSerializationType(); } else { t.SerializationType = (IAttributeSerializationDefinition)Activator.CreateInstance(serializationType); } ExamineHelper.SetEntityDatesFromSearchResult(t, s); }); #endregion #region EntitySchema -> NestedHiveIndexOperation //create a map that supports inheritance as we don't want to create a map for all EntitySchemas this.CreateMap <EntitySchema, NestedHiveIndexOperation>(true) .CreateUsing(x => new NestedHiveIndexOperation()) .ForMember(x => x.Entity, opt => opt.MapFrom(y => y)) .ForMember(x => x.OperationType, opt => opt.MapFrom(y => IndexOperationType.Add)) .ForMember(x => x.Id, opt => opt.MapFrom(y => new Lazy <string>(() => y.Id.Value.ToString()))) //need to lazy load as it might not be set .ForMember(x => x.ItemCategory, opt => opt.MapFrom(y => typeof(EntitySchema).Name)) .ForMember(x => x.Fields, opt => opt.MapUsing <EntitySchemaToIndexFields>()) .AfterMap((s, t) => { //Create sub operations for each of its children (both attribute definitions and groups) foreach (var op in s.AttributeDefinitions.Select(Map <AttributeDefinition, NestedHiveIndexOperation>) .Concat(s.AttributeGroups.Select(Map <AttributeGroup, NestedHiveIndexOperation>))) { //NOTE: we need to add this schema id to the fields otherwise we would just add this in the mapping operation for AttributeDefinition if it exposed the schema it belonged to op.Fields.Add(FixedIndexedFields.SchemaId, new Lazy <ItemField>(() => new ItemField(s.Id.Value.ToString()))); //need to add it as lazy since the id might not exist yet t.SubIndexOperations.Add(op); } //get the relations s.MapRelations(t, this); }); #endregion #region TypedEntity -> NestedHiveIndexOperation this.CreateMap(new TypedEntityToIndexOperation(this), true); #endregion #region Relation -> NestedHiveIndexOperation this.CreateMap <IReadonlyRelation <IRelatableEntity, IRelatableEntity>, NestedHiveIndexOperation>(true) .CreateUsing(x => new NestedHiveIndexOperation()) .ForMember(x => x.Entity, opt => opt.MapFrom(y => y)) .ForMember(x => x.OperationType, opt => opt.MapFrom(y => IndexOperationType.Add)) //need to lazy load as ids might not be set yet, this is also a 'composite' id of Source,Dest,Type .ForMember(x => x.Id, opt => opt.MapFrom(y => new Lazy <string>(y.GetCompositeId))) .ForMember(x => x.ItemCategory, opt => opt.MapFrom(y => "Relation")) .ForMember(x => x.Fields, opt => opt.MapUsing <RelationToIndexFields>()); #endregion #region Revision<TypedEntity> -> NestedHiveIndexOperation this.CreateMap <Revision <TypedEntity>, NestedHiveIndexOperation>(true) .CreateUsing(x => new NestedHiveIndexOperation()) .AfterMap((s, t) => { //first, map the underlying TypedEntity var op = Map <TypedEntity, NestedHiveIndexOperation>(s.Item); //map all of the properties... we don't have to explicitly declare a map for this, the engine will automatically just create one Map(op, t); //ensure the rest of the revision data _helper.EnsureRevisionDataForIndexOperation(s, t); }); #endregion #region AttributeType -> NestedHiveIndexOperation //create a map that supports inheritance as we don't want to create a map for all EntitySchemas... this would also be impossible this.CreateMap <AttributeType, NestedHiveIndexOperation>(true) .CreateUsing(x => new NestedHiveIndexOperation()) .ForMember(x => x.Entity, opt => opt.MapFrom(y => y)) .ForMember(x => x.OperationType, opt => opt.MapFrom(y => IndexOperationType.Add)) .ForMember(x => x.Id, opt => opt.MapFrom(y => new Lazy <string>(() => y.Id.Value.ToString()))) //need to lazy load as it might not be set .ForMember(x => x.ItemCategory, opt => opt.MapFrom(y => typeof(AttributeType).Name)) .ForMember(x => x.Fields, opt => opt.MapUsing(new AttributeTypeToIndexFields(_helper))); #endregion #region AttributeGroup -> NestedHiveIndexOperation //create a map that supports inheritance as we don't want to create a map for all EntitySchemas... this would also be impossible this.CreateMap <AttributeGroup, NestedHiveIndexOperation>(true) .CreateUsing(x => new NestedHiveIndexOperation()) .ForMember(x => x.Entity, opt => opt.MapFrom(y => y)) .ForMember(x => x.OperationType, opt => opt.MapFrom(y => IndexOperationType.Add)) .ForMember(x => x.Id, opt => opt.MapFrom(y => new Lazy <string>(() => y.Id.Value.ToString()))) //need to lazy load as it might not be set .ForMember(x => x.ItemCategory, opt => opt.MapFrom(y => typeof(AttributeGroup).Name)) .ForMember(x => x.Fields, opt => opt.MapUsing <AttributeGroupToIndexFields>()); #endregion #region AttributeDefinition -> NestedHiveIndexOperation //create a map that supports inheritance as we don't want to create a map for all EntitySchemas... this would also be impossible this.CreateMap <AttributeDefinition, NestedHiveIndexOperation>(true) .CreateUsing(x => new NestedHiveIndexOperation()) .ForMember(x => x.Entity, opt => opt.MapFrom(y => y)) .ForMember(x => x.OperationType, opt => opt.MapFrom(y => IndexOperationType.Add)) .ForMember(x => x.Id, opt => opt.MapFrom(y => new Lazy <string>(() => y.Id.Value.ToString()))) //need to lazy load as it might not be set .ForMember(x => x.ItemCategory, opt => opt.MapFrom(y => typeof(AttributeDefinition).Name)) .ForMember(x => x.Fields, opt => opt.MapUsing <AttributeDefinitionToIndexFields>()) .AfterMap((s, t) => { //Add sub operation for it's AttributeType t.SubIndexOperations.Add(Map <AttributeType, NestedHiveIndexOperation>(s.AttributeType)); }); #endregion }
public SearchResultToTypedEntity(ExamineHelper helper, AbstractFluentMappingEngine engine) : base(engine) { _helper = helper; }
public AttributeTypeToIndexFields(ExamineHelper helper) { _helper = helper; }
public DependencyHelper(ExamineHelper helper, ProviderMetadata providerMetadata) : base(providerMetadata) { ExamineHelper = helper; }
protected override void DisposeResources() { ExamineHelper.Dispose(); }
/// <summary> /// Performs installation of the Zoombraco package. /// Note: At this point in time it is not possible to register the package as installed to the CMS. This means that we are /// unable to automatically uninstall the package. /// </summary> /// <param name="umbracoApplication"> /// The current <see cref="UmbracoApplicationBase"/> /// </param> /// <param name="applicationContext"> /// The Umbraco <see cref="ApplicationContext"/> for the current application. /// </param> /// <returns>The <see cref="bool"/></returns> public static bool Install(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { if (!applicationContext.IsConfigured) { LogHelper.Info <ZoombracoBootstrapper>("Umbraco is not configured. Aborting Zoombraco setup."); return(false); } // Check our versioning. Assembly assembly = VersionParser.Assembly; SemVersion currentVersion = VersionParser.ZoombracoProductVersion(); SemVersion installedVersion = ZoombracoConfiguration.Instance.ProductVersion; if (installedVersion >= currentVersion) { LogHelper.Info <ZoombracoBootstrapper>($"Zoombraco {installedVersion} is installed and up-to-date. Aborting Zoombraco setup."); return(true); } try { // Install our package. string resourceName; using (Stream package = EmbeddedResourceHelper.GetResource(assembly, "package.xml", out resourceName)) { PackageHelper packageHelper = new PackageHelper(package, applicationContext); packageHelper.Unpack(); using (Stream meta = EmbeddedResourceHelper.GetResource(assembly, "_Meta.cshtml", out resourceName)) using (Stream sitemap = EmbeddedResourceHelper.GetResource(assembly, "XmlSitemap.cshtml", out resourceName)) using (Stream error = EmbeddedResourceHelper.GetResource(assembly, "Error.cshtml", out resourceName)) { packageHelper.UnpackFile(meta, "_Meta.cshtml"); packageHelper.UnpackFile(sitemap, "XmlSitemap.cshtml"); packageHelper.UnpackFile(error, "Error.cshtml"); } } // Edit the Examine config file. string settings = Path.Combine(IOHelper.GetRootDirectorySafe(), "Config", "ExamineSettings.config"); if (!File.Exists(settings)) { LogHelper.Error <ZoombracoBootstrapper>($"Unable to install the Zoombraco. No ExamineSetting.config exists at the path {settings}", new FileNotFoundException()); return(false); } using (FileStream stream = File.Open(settings, FileMode.Open, FileAccess.ReadWrite)) { ExamineHelper examineHelper = new ExamineHelper(stream); examineHelper.UpdateExamineAnalyzer(); } // Set default values. if (installedVersion == new SemVersion(0)) { ZoombracoConfiguration.SaveSetting(ZoombracoConstants.Configuration.OutputCacheDuration, "0"); ZoombracoConfiguration.SaveSetting(ZoombracoConstants.Configuration.ImageCdnRequestTimeout, "2000"); ZoombracoConfiguration.SaveSetting(ZoombracoConstants.Configuration.ModelsBuilderEnabled, "false"); } // Update our version number ZoombracoConfiguration.SaveSetting(ZoombracoConstants.Configuration.Version, currentVersion.ToSemanticString()); return(true); } catch (Exception e) { LogHelper.Error <ZoombracoBootstrapper>("Unable to install the Zoombraco.", e); return(false); } }
public SearchResultToRevisionData(ExamineHelper helper) { _helper = helper; }