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); }
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); }
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); }
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 }); }