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(),
                });
            });
        }
Beispiel #2
0
        //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]));
        }