public TripleStoreProfile(TripleRecordStore store) { _store = store; // Вычисление "важных" кодов cod_rdftype = store.CodeEntity("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); // Зафиксирован? 0; cod_delete = store.CodeEntity("http://fogid.net/o/delete"); cod_name = store.CodeEntity("http://fogid.net/o/name"); CreateMap <object, RecordField>().ConstructUsing((triples, context) => { if (!(triples is object[] dup)) { return(null); } return(new RecordField() { Property = store.Decode((int)dup[0]), Value = (string)dup[1] }); }); CreateMap <object, RecordProperty>().ConstructUsing((triples, context) => { if (!(triples is object[] dup)) { return(null); } return(new RecordProperty() { Property = store.DecodeEntity((int)dup[0]), Value = new Record() { Id = store.DecodeEntity((int)dup[1]) } }); }); CreateMap <object, RecordInverseProperty>().ConstructUsing((source, context) => { if (!(source is object[] triples)) { return(null); } int cid = (int)triples[0]; object[] found = ((object[])triples[1]).Cast <object[]>().FirstOrDefault(dup => (int)dup[1] == cid); return(new RecordInverseProperty() { Property = store.DecodeEntity((int)found[0]), Value = new Record() { Id = store.DecodeEntity((int)triples[0]) } }); }); CreateMap <object, Record>().ConstructUsing((source, context) => { if (!(source is object[] triples)) { return(null); } if (context.Options.Items["Format"] is RecordFormat format) { //todo use format recursive return(new Record() { Id = store.DecodeEntity((int)triples[0]), Type = GetRecordType(source), Fields = context.Mapper.Map <RecordField[]>(((object[])triples[2])), Directs = context.Mapper.Map <RecordProperty[]>((object[])triples[1]) }); } return(new Record() { Id = store.DecodeEntity((int)triples[0]), Type = GetRecordType(source), Fields = context.Mapper.Map <RecordField[]>((object[])triples[2]), Directs = context.Mapper.Map <RecordProperty[]>((object[])triples[1]) }); }); CreateMap <object, RecordWithInverses>().ConstructUsing((source, context) => { if (!(source is object[] triples)) { return(null); } return(new RecordWithInverses() { Id = store.DecodeEntity((int)triples[0]), Type = GetRecordType(source), Fields = context.Mapper.Map <RecordField[]>((object[])triples[2]), Directs = context.Mapper.Map <RecordProperty[]>((object[])triples[1]), Inverses = context.Mapper.Map <IEnumerable <RecordInverseProperty> >(store.GetRefers((int)triples[0])) ?.ToArray() }); }); CreateMap <Record, XElement>().ConvertUsing((record, context) => { if (record == null) { return(null); } XElement xres = new XElement("record", new XAttribute("id", record.Id), record.Type == null ? null : new XAttribute("type", record.Type), record.Fields?.Select(dup => new XElement("field", new XAttribute("prop", dup.Property), dup.Value)), record.Directs?.Select(dup => new XElement("direct", new XAttribute("prop", dup.Property), new XElement("record", new XAttribute("id", dup.Value.Id))))); return(xres); }); CreateMap <RecordWithInverses, XElement>().ConvertUsing((record, context) => record == null ? null : new XElement("record", new XAttribute("id", record.Id), record.Type == null ? null : new XAttribute("type", record.Type), record.Fields?.Select(dup => new XElement("field", new XAttribute("prop", dup.Property), dup.Value)), record.Directs?.Select(dup => new XElement("direct", new XAttribute("prop", dup.Property), new XElement("record", new XAttribute("id", dup.Value.Id)))), record.Inverses?.Select(dup => new XElement("direct", new XAttribute("prop", dup.Property), new XElement("record", new XAttribute("id", dup.Value.Id)))))); // ============================== Редактирование ================================ CreateMap <Record, object>().ConvertUsing((record, context) => { int cid = store.CodeEntity(record.Id); return(new object[] { cid, Enumerable.Repeat(new object[] { cod_rdftype, store.CodeEntity(record.Type) }, 1) .Concat(record.Directs .Select(el => new object[] { store.CodeEntity(el.Property), store.CodeEntity(el.Value.Id) })).ToArray(), record.Fields .Select(el => new object[] { store.CodeEntity(el.Property), el.Value }).ToArray() }); }); CreateMap <XElement, Record>().ConvertUsing((xRecord, context) => { var xAbout = xRecord.Attribute("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about"); if (xAbout == null) { return(null); } var props = xRecord.Elements().Select(x => (x, resource: x.Attribute("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource"), property: "http://fogid.net/o/" + x.Name.LocalName)) .GroupBy(el => el.resource != null) .ToArray(); string id = xAbout.Value; string tp = "http://fogid.net/o/" + xRecord.Name.LocalName; return(new Record() { Id = id, Type = tp, Fields = props.Where(g => !g.Key).SelectMany(x => x) .Select(el => new RecordField { Property = el.property, Value = el.x.Value }) .ToArray(), Directs = props.Where(g => g.Key).SelectMany(x => x) .Select(el => new RecordProperty { Property = el.property, Value = new Record { Id = el.resource.Value } }).ToArray(), }); }); }
//public override void LoadFromCassettesExpress(IEnumerable<string> fogfilearr, Action<string> turlog, Action<string> convertlog) //{ // store.Clear(); // // Нужно для чтения в кодировке windows-1251. Нужен также Nuget System.Text.Encoding.CodePages // //var v = System.Text.Encoding.CodePagesEncodingProvider.Instance; // //System.Text.Encoding.RegisterProvider(v); // // Готовим битовый массив для отметки того, что хеш id уже "попадал" в этот бит // int ba_volume = 1024 * 1024; // int mask = ~((-1) << 20); // System.Collections.BitArray bitArr = new System.Collections.BitArray(ba_volume); // // Хеш-функция будет ограничена 20-ю разрядами, массив и функция нужны только временно // Func<string, int> Hash = s => s.GetHashCode() & mask; // // Словарь // Dictionary<string, DateTime> lastDefs = new Dictionary<string, DateTime>(); // int cnt = 0; // // Первый проход сканирования фог-файлов // foreach (string fog_name in fogfilearr) // { // // Чтение фога // XElement fog = XElement.Load(fog_name); // // Перебор записей // foreach (XElement rec in fog.Elements()) // { // XElement record = ConvertXElement(rec); // cnt++; // if (record.Name == "delete" // || record.Name == "{http://fogid.net/o/}delete" // || record.Name == "substitute" // || record.Name == "{http://fogid.net/o/}substitute" // ) continue; // string id = record.Attribute("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about").Value; // CheckAndSet(bitArr, Hash, lastDefs, id, record.Attribute("mT")?.Value); // } // } // cnt = 0; // // Второй проход сканирования фог-файлов // IEnumerable<object> objectFlow = fogfilearr.SelectMany(fog_name => // { // XElement fog = XElement.Load(fog_name); // // Перебор записей // return fog.Elements() // .Where(rec => rec.Name != "delete" // && rec.Name != "{http://fogid.net/o/}delete" // && rec.Name != "substitute" // && rec.Name != "{http://fogid.net/o/}substitute") // .Select(rec => ConvertXElement(rec)) // .Where(record => // { // string id = record.Attribute("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about").Value; // //int code = Hash(id); // bool toprocess = false; // if (lastDefs.TryGetValue(id, out DateTime saved)) // { // DateTime mT = DateTime.MinValue; // XAttribute mT_att = record.Attribute("mT"); // if (mT_att != null) { mT = DateTime.Parse(mT_att.Value); } // // Оригинал если отметка времени больше или равна // if (mT >= saved) // { // // сначала обеспечим приоритет перед другими решениями // lastDefs.Remove(id); // lastDefs.Add(id, mT); // // оригинал! // // Обрабатываем! // toprocess = true; // } // } // else // { // // это единственное определение! // // Обрабатываем! // toprocess = true; // } // return toprocess; // }) // .Select(record => // { // string id = record.Attribute("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about").Value; // int rec_type = store.CodeEntity("http://fogid.net/o/" + record.Name.LocalName); // int id_ent = store.CodeEntity(id); // object[] orecord = new object[] { // id_ent, // (new object[] { new object[] { cod_rdftype, rec_type } }).Concat( // record.Elements().Where(el => el.Attribute(ONames.rdfresource) != null) // .Select(subel => // { // int prop = store.CodeEntity(subel.Name.NamespaceName + subel.Name.LocalName); // return new object[] { prop, store.CodeEntity(subel.Attribute(ONames.rdfresource).Value) }; // })).ToArray() // , // record.Elements().Where(el => el.Attribute(ONames.rdfresource) == null) // .Select(subel => // { // int prop = store.CodeEntity(subel.Name.NamespaceName + subel.Name.LocalName); // return new object[] { prop, subel.Value }; // }) // .ToArray() // }; // return orecord; // }); // }); // store.Load(objectFlow); // store.Build(); // store.Flush(); // GC.Collect(); //} private string GetRecordId(object rec) { var tri = (object[])rec; return(store.Decode((int)tri[0])); }