Пример #1
0
        private async Task <APEntity> _build(APTripleEntity mold)
        {
            var triples = (await _connection.QueryAsync <Triple>("select * from \"Triples\" where \"SubjectEntityId\" = @Id", new { Id = mold.EntityId })).ToList();

            await _preload(triples.Select(a => a.SubjectId)
                           .Concat(triples.Where(a => a.TypeId.HasValue).Select(a => a.TypeId.Value))
                           .Concat(triples.Where(a => a.AttributeId.HasValue).Select(a => a.AttributeId.Value)
                                   .Concat(triples.Select(a => a.PredicateId))));

            var rdfType = await ReverseAttribute("rdf:type", true);

            var rdfEnd = await ReverseAttribute("rdf:rest", true);

            var result = _buildRaw(mold, triples, rdfType.Value, rdfEnd.Value);

            return(result);
        }
Пример #2
0
        public async Task <APEntity> GetEntity(string id, bool doRemote)
        {
            if (id == null)
            {
                return(null);
            }
            if (_quickMap.ContainsKey(id))
            {
                return(_quickMap[id]);
            }

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var attr = await ReverseAttribute(id, false);

            APTripleEntity tripleEntity = null;

            if (attr != null)
            {
                tripleEntity = await _connection.QueryFirstOrDefaultAsync <APTripleEntity>("select * from \"TripleEntities\" where \"IdId\" = @IdId limit 1", new { IdId = attr.Value });
            }
            if (tripleEntity == null)
            {
                return(null);
            }

            var b = await _build(tripleEntity);

            stopwatch.Stop();

            _logger.LogWarning("Getting ID {id} took {time}", b.Id, stopwatch.Elapsed);
            _quickMap[id] = b;
            return(b);
        }
Пример #3
0
        public async Task <APEntity> StoreEntity(APEntity entity)
        {
            var idid = await ReverseAttribute(entity.Id, false);

            var exists = await _connection.QueryFirstOrDefaultAsync <APTripleEntity>("select * from \"TripleEntities\" where \"EntityId\" = @Id or \"IdId\" = @IdId limit 1", new { Id = entity.DbId, IdId = idid });

            if (exists == null)
            {
                entity.Updated = DateTime.Now;
                var dbEntity = new APTripleEntity {
                    Updated = entity.Updated, IsOwner = entity.IsOwner, Type = entity.Type
                };
                var attr = (await ReverseAttribute(entity.Id, true)).Value;
                dbEntity.IdId     = attr;
                dbEntity.EntityId = await _connection.ExecuteScalarAsync <int>("insert into \"TripleEntities\" (\"Updated\", \"IsOwner\", \"Type\", \"IdId\") values (@Updated, @IsOwner, @Type, @IdId) returning \"EntityId\"", dbEntity);

                var allTriples = await _newTriples(entity);

                foreach (var triple in allTriples)
                {
                    triple.SubjectEntityId = dbEntity.EntityId;
                }

                await _connection.ExecuteAsync("insert into \"Triples\" (\"SubjectId\", \"SubjectEntityId\", \"PredicateId\", \"AttributeId\", \"TypeId\", \"Object\") " +
                                               "values (@SubjectId, @SubjectEntityId, @PredicateId, @AttributeId, @TypeId, @Object)", allTriples);

                exists = dbEntity;
            }
            else
            {
                var triples = (await _connection.QueryAsync <Triple>("select * from \"Triples\" where \"SubjectEntityId\" = @SubjectEntityId", new { SubjectEntityId = exists.EntityId })).GroupBy(a => a.PredicateId).ToDictionary(a => a.Key, b => b);
                var compare = (await _newTriples(entity)).GroupBy(a => a.PredicateId).ToDictionary(a => a.Key, b => b);

                var allKeys = new HashSet <int>(triples.Keys.Concat(compare.Keys));
                foreach (var key in allKeys)
                {
                    if (compare.ContainsKey(key) && !triples.ContainsKey(key))
                    {
                        foreach (var triple in compare[key])
                        {
                            triple.SubjectEntityId = exists.EntityId;
                        }

                        await _connection.ExecuteAsync("insert into \"Triples\" (\"SubjectId\", \"SubjectEntityId\", \"PredicateId\", \"AttributeId\", \"TypeId\", \"Object\") values (@SubjectId, @SubjectEntityId, @PredicateId, @AttributeId, @TypeId, @Object)", compare[key]);
                    }
                    else if (!compare.ContainsKey(key) && triples.ContainsKey(key))
                    {
                        await _connection.ExecuteAsync("delete from \"Triples\" where \"TripleId\" = any(@Ids)", new { Ids = triples[key].Select(a => a.TripleId).ToList() });
                    }
                    else
                    {
                        await _connection.ExecuteAsync("delete from \"Triples\" where \"TripleId\" = any(@Ids)", new { Ids = triples[key].Select(a => a.TripleId).ToList() });

                        foreach (var triple in compare[key])
                        {
                            triple.SubjectEntityId = exists.EntityId;
                        }

                        await _connection.ExecuteAsync("insert into \"Triples\" (\"SubjectId\", \"SubjectEntityId\", \"PredicateId\", \"AttributeId\", \"TypeId\", \"Object\") values (@SubjectId, @SubjectEntityId, @PredicateId, @AttributeId, @TypeId, @Object)", compare[key]);
                    }
                }
            }

            entity.DbId = exists.EntityId;

            return(entity);
        }
Пример #4
0
        private APEntity _buildRaw(APTripleEntity mold, IEnumerable <Triple> triples, int rdfType, int rdfEnd)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var subjects = triples.GroupBy(a => a.SubjectId).ToDictionary(a => a.Key, a => a);
            Dictionary <int, ASObject> objects = subjects.ToDictionary(a => a.Key, a => new ASObject {
                Id = _attributeMapping[a.Key]
            });
            var listEnds   = new HashSet <int>();
            var blankNodes = new Dictionary <int, Tuple <ASObject, string> >();
            var listParts  = triples.Where(a => a.PredicateId == rdfEnd).ToDictionary(a => a.AttributeId.Value, a => a.SubjectId);

            foreach (var obj in objects)
            {
                var result = obj.Value;

                if (result.Id.StartsWith("_:"))
                {
                    result.Id = null;
                }

                result.Type.AddRange(subjects[obj.Key].Where(a => a.PredicateId == rdfType).Select(a => _attributeMapping[a.AttributeId.Value]));

                foreach (var triple in subjects[obj.Key])
                {
                    if (triple.PredicateId == rdfType)
                    {
                        continue;
                    }

                    var term         = new ASTerm();
                    var predicateUrl = _attributeMapping[triple.PredicateId];

                    if (triple.AttributeId.HasValue && !listParts.ContainsValue(triple.AttributeId.Value) && objects.ContainsKey(triple.AttributeId.Value) && _attributeMapping[triple.AttributeId.Value].StartsWith("_:"))
                    {
                        term.SubObject = objects[triple.AttributeId.Value];
                    }
                    else
                    {
                        if (triple.TypeId.HasValue)
                        {
                            term.Type = _attributeMapping[triple.TypeId.Value];
                        }

                        if (triple.AttributeId.HasValue)
                        {
                            term.Id = _attributeMapping[triple.AttributeId.Value];
                        }

                        term.Primitive = _tripleToJson(triple.Object, term.Type);
                        if (_defaultTypes.Contains(term.Type))
                        {
                            term.Type = null;
                        }

                        if (predicateUrl == "rdf:rest")
                        {
                            if (term.Id == "rdf:nil")
                            {
                                listEnds.Add(triple.SubjectId);
                            }
                            listParts[triple.AttributeId.Value] = triple.SubjectId;
                        }

                        if (term.Id?.StartsWith("_:") == true)
                        {
                            blankNodes[triple.AttributeId.Value] = new Tuple <ASObject, string>(result, predicateUrl);
                        }
                    }


                    result[predicateUrl].Add(term);
                }
            }

            foreach (var listEnd in listEnds)
            {
                var listId = listEnd;
                var list   = new List <ASTerm>();
                list.Add(objects[listId]["rdf:first"].First());
                while (listParts.ContainsKey(listId))
                {
                    listId = listParts[listId];
                    list.Add(objects[listId]["rdf:first"].First());
                }

                if (blankNodes.ContainsKey(listId))
                {
                    blankNodes[listId].Deconstruct(out var obj, out var name);

                    list.Reverse();

                    obj[name].Clear();
                    obj[name].AddRange(list);
                }
            }

            var mainObj = objects[mold.IdId];

            stopwatch.Stop();
            _logger.LogWarning("Molding {id} from cache took {time}", mainObj.Id, stopwatch.Elapsed);
            return(new APEntity {
                Data = mainObj, Id = mainObj.Id, Updated = mold.Updated, IsOwner = mold.IsOwner, Type = mold.Type, DbId = mold.EntityId
            });
        }