/// <summary> /// Adds a Namespace at the Current Nesting Level /// </summary> /// <param name="prefix">Prefix</param> /// <param name="uri">Namespace URI</param> public void AddNamespace(string prefix, Uri uri) { NestedMapping mapping = new NestedMapping(prefix, uri, this._level); if (!this._prefixes.ContainsKey(uri.GetEnhancedHashCode())) this._prefixes.Add(uri.GetEnhancedHashCode(), new List<NestedMapping>()); if (this._uris.ContainsKey(prefix)) { //Is it defined on the current nesting level? if (this._uris[prefix].Any(m => m.Level == this._level)) { //If it is then we override it this._uris[prefix].RemoveAll(m => m.Level == this._level); this._prefixes[uri.GetEnhancedHashCode()].RemoveAll(m => m.Level == this._level); this._uris[prefix].Add(mapping); this._prefixes[uri.GetEnhancedHashCode()].Add(mapping); this.RaiseNamespaceModified(prefix, uri); } else { //If not we simply add it this._uris[prefix].Add(mapping); this._prefixes[uri.GetEnhancedHashCode()].Add(mapping); this.RaiseNamespaceAdded(prefix, uri); } } else { //Not yet defined so add it this._uris.Add(prefix, new List<NestedMapping>()); this._uris[prefix].Add(mapping); this._prefixes[uri.GetEnhancedHashCode()].Add(mapping); this.RaiseNamespaceAdded(prefix, uri); } }
public void AddNamespace(string prefix, Uri uri) { OffsetMapping mapping = new OffsetMapping(prefix, uri, this._offset); if (!this._prefixes.ContainsKey(uri.GetEnhancedHashCode())) this._prefixes.Add(uri.GetEnhancedHashCode(), new List<OffsetMapping>()); if (this._uris.ContainsKey(prefix)) { //Is it defined at the current offset level? if (this._uris[prefix].Any(m => m.Offset == this._offset)) { //If it is then we override it this._uris[prefix].RemoveAll(m => m.Offset == this._offset); this._prefixes[uri.GetEnhancedHashCode()].RemoveAll(m => m.Offset == this._offset); this._uris[prefix].Add(mapping); this._prefixes[uri.GetEnhancedHashCode()].Add(mapping); this.OnNamespaceModified(prefix, uri); } else { //If not we simply add it this._uris[prefix].Add(mapping); this._prefixes[uri.GetEnhancedHashCode()].Add(mapping); this.OnNamespaceAdded(prefix, uri); } } else { //Not yet defined so add it this._uris.Add(prefix, new List<OffsetMapping>()); this._uris[prefix].Add(mapping); this._prefixes[uri.GetEnhancedHashCode()].Add(mapping); this.OnNamespaceAdded(prefix, uri); } }
public void ToCache(Uri requestUri, Uri responseUri, IGraph g, String etag) { //Cache a local copy of the Graph try { bool cacheTwice = !requestUri.ToString().Equals(responseUri.ToString() , StringComparison.OrdinalIgnoreCase); if (this._canCacheGraphs) { String graph = Path.Combine(this._graphDir, requestUri.GetSha256Hash()); this._ttlwriter.Save(g, graph); //If applicable also cache under the responseUri if (cacheTwice) { graph = Path.Combine(this._graphDir, responseUri.GetSha256Hash()); this._ttlwriter.Save(g, graph); } } //Cache the ETag if present if (this._canCacheETag && etag != null && !etag.Equals(String.Empty)) { int id = requestUri.GetEnhancedHashCode(); bool requireAdd = false; if (this._etags.ContainsKey(id)) { if (!this._etags[id].Equals(etag)) { //If the ETag has changed remove it and then re-add it this.RemoveETag(requestUri); requireAdd = true; } } else { requireAdd = true; } if (requireAdd) { //Add a New ETag this._etags.Add(id, etag); using (StreamWriter writer = new StreamWriter(this._etagFile, true, Encoding.UTF8)) { writer.WriteLine(id + "\t" + etag); writer.Close(); } } //Cache under the Response URI as well if applicable if (cacheTwice) { id = responseUri.GetEnhancedHashCode(); requireAdd = false; if (this._etags.ContainsKey(id)) { if (!this._etags[id].Equals(etag)) { //If the ETag has changed remove it and then re-add it this.RemoveETag(responseUri); requireAdd = true; } } else { requireAdd = true; } if (requireAdd) { using (StreamWriter writer = new StreamWriter(this._etagFile, true, Encoding.UTF8)) { writer.WriteLine(id + "\t" + etag); writer.Close(); } } } } } catch (IOException) { //Ignore - if we get an IO Exception we failed to cache somehow } catch (RdfOutputException) { //Ignore - if we get an RDF Output Exception then we failed to cache } }
public IRdfHandler ToCache(Uri requestUri, Uri responseUri, String etag) { IRdfHandler handler = null; try { bool cacheTwice = !requestUri.ToString().Equals(responseUri.ToString(), StringComparison.OrdinalIgnoreCase); //Cache the ETag if present if (this._canCacheETag && etag != null && !etag.Equals(String.Empty)) { int id = requestUri.GetEnhancedHashCode(); bool requireAdd = false; if (this._etags.ContainsKey(id)) { if (!this._etags[id].Equals(etag)) { //If the ETag has changed remove it and then re-add it this.RemoveETag(requestUri); requireAdd = true; } } else { requireAdd = true; } if (requireAdd) { //Add a New ETag this._etags.Add(id, etag); using (StreamWriter writer = new StreamWriter(this._etagFile, true, Encoding.UTF8)) { writer.WriteLine(id + "\t" + etag); writer.Close(); } } //Cache under the Response URI as well if applicable if (cacheTwice) { id = responseUri.GetEnhancedHashCode(); requireAdd = false; if (this._etags.ContainsKey(id)) { if (!this._etags[id].Equals(etag)) { //If the ETag has changed remove it and then re-add it this.RemoveETag(responseUri); requireAdd = true; } } else { requireAdd = true; } if (requireAdd) { using (StreamWriter writer = new StreamWriter(this._etagFile, true, Encoding.UTF8)) { writer.WriteLine(id + "\t" + etag); writer.Close(); } } } } //Then if we are caching Graphs return WriteThroughHandlers to do the caching for us if (this._canCacheGraphs) { String graph = Path.Combine(this._graphDir, requestUri.GetSha256Hash()); handler = new WriteThroughHandler(this._formatterType, new StreamWriter(graph), true); if (cacheTwice) { graph = Path.Combine(this._graphDir, responseUri.GetSha256Hash()); handler = new MultiHandler(new IRdfHandler[] { handler, new WriteThroughHandler(this._formatterType, new StreamWriter(graph), true) }); } } } catch (IOException) { //Ignore - if we get an IO Exception we failed to cache somehow } catch (RdfOutputException) { //Ignore - if we get an RDF Output Exception then we failed to cache } return handler; }
/// <summary> /// Remove the ETag record for the given URI /// </summary> /// <param name="u">URI</param> public void RemoveETag(Uri u) { try { if (this._canCacheETag) { if (this._etags.ContainsKey(u.GetEnhancedHashCode())) { this._etags.Remove(u.GetEnhancedHashCode()); //If we did remove an ETag then we need to rewrite our ETag cache file using (StreamWriter writer = new StreamWriter(this._etagFile, false, Encoding.UTF8)) { foreach (KeyValuePair<int, String> etag in this._etags) { writer.WriteLine(etag.Key + "\t" + etag.Value); } writer.Close(); } } } } catch (IOException) { //If an IO Exception occurs ignore it, something went wrong with cache alteration } }
/// <summary> /// Gets the ETag for the given URI /// </summary> /// <param name="u">URI</param> /// <returns></returns> /// <exception cref="KeyNotFoundException">Thrown if there is no ETag for the given URI</exception> public String GetETag(Uri u) { if (this._canCacheETag) { if (this._nocache.Contains(u.GetSha256Hash())) throw new KeyNotFoundException("No ETag was found for the URI " + u.ToString()); int id = u.GetEnhancedHashCode(); if (this._etags.ContainsKey(id)) { return this._etags[id]; } else { throw new KeyNotFoundException("No ETag was found for the URI " + u.ToString()); } } else { throw new KeyNotFoundException("No ETag was found for the URI " + u.ToString()); } }
/// <summary> /// Gets whether there is an ETag for the given URI /// </summary> /// <param name="u">URI</param> /// <returns></returns> public bool HasETag(Uri u) { if (this._canCacheETag) { if (this._nocache.Contains(u.GetSha256Hash())) return false; return this._etags.ContainsKey(u.GetEnhancedHashCode()) && this.HasLocalCopy(u, false); } else { return false; } }
/// <summary> /// Selects Statements from the Source based on a Template /// </summary> /// <param name="template">Statement Template</param> /// <param name="sink">Sink to stream results to</param> public void Select(Statement template, StatementSink sink) { //Convert Template to an Enumerable IEnumerable<Triple> ts = Enumerable.Empty<Triple>(); int hash; if (template.Meta != Statement.DefaultMeta && template.Meta != null) { //Select from the specific Graph if it exists Uri graphUri; if (template.Meta.Uri == null) { hash = new Uri(GraphCollection.DefaultGraphUri).GetEnhancedHashCode(); graphUri = null; } else { graphUri = new Uri(template.Meta.Uri); hash = graphUri.GetEnhancedHashCode(); } if (this._store.HasGraph(graphUri)) { ts = this.TemplateToEnumerable(template, this._store.Graph(graphUri)); SemWebMapping mapping = this.GetMapping(hash, this._store.Graph(graphUri)); foreach (Triple t in ts) { //Keep streaming Triples until the sink tells us to stop Statement stmt = SemWebConverter.ToSemWeb(t, mapping); if (!sink.Add(stmt)) return; } } } else { //Output the results from each Graph in turn foreach (IGraph g in this._store.Graphs) { Entity graphUri; if (g.BaseUri == null) { hash = new Uri(GraphCollection.DefaultGraphUri).GetEnhancedHashCode(); graphUri = new Entity(GraphCollection.DefaultGraphUri); } else { hash = g.BaseUri.GetEnhancedHashCode(); graphUri = new Entity(g.BaseUri.ToString()); } SemWebMapping mapping = this.GetMapping(hash, g); foreach (Triple t in this.TemplateToEnumerable(template, g)) { Statement stmt = SemWebConverter.ToSemWeb(t, mapping); stmt.Meta = graphUri; if (!sink.Add(stmt)) return; } } } }
/// <summary> /// Adds a statement to this Source /// </summary> /// <param name="statement">Statement</param> /// <returns></returns> public bool Add(Statement statement) { IGraph g; Uri graphUri; int hash; //Set the Graph URI based on the Statement Meta field if (statement.Meta != Statement.DefaultMeta && statement.Meta.Uri != null) { if (statement.Meta.Uri.Equals(GraphCollection.DefaultGraphUri)) { graphUri = null; hash = new Uri(GraphCollection.DefaultGraphUri).GetEnhancedHashCode(); } else { graphUri = new Uri(statement.Meta.Uri); hash = graphUri.GetEnhancedHashCode(); } } else { graphUri = null; hash = new Uri(GraphCollection.DefaultGraphUri).GetEnhancedHashCode(); } if (!this._store.HasGraph(graphUri)) { g = new Graph(); if (graphUri != null) g.BaseUri = graphUri; this._store.Add(g); } else { g = this._store.Graph(graphUri); } //Assert into the appropriate Graph g.Assert(SemWebConverter.FromSemWeb(statement, this.GetMapping(hash, g))); //We never ask the sink to stop streaming statements so we always return true return true; }
/// <summary> /// Gets the Namespace Prefix for the given URI at the current Nesting Level /// </summary> /// <param name="uri">Namespace URI</param> /// <returns></returns> public string GetPrefix(Uri uri) { int hash = uri.GetEnhancedHashCode(); if (this._prefixes.ContainsKey(hash)) { return this._prefixes[hash].Last().Prefix; } else { throw new RdfException("The Prefix for the given URI '" + uri.ToString() + "' is not known by the in-scope NamespaceMapper"); } }
/// <summary> /// Adds a Namespace to the Namespace Map /// </summary> /// <param name="prefix">Namespace Prefix</param> /// <param name="uri">Namespace Uri</param> public virtual void AddNamespace(String prefix, Uri uri) { int hash = uri.GetEnhancedHashCode(); if (!this._uris.ContainsKey(prefix)) { //Add a New Prefix this._uris.Add(prefix, uri); if (!this._prefixes.ContainsKey(hash)) { //Add a New Uri this._prefixes.Add(hash, prefix); this.OnNamespaceAdded(prefix, uri); } else { //Check whether the Namespace Uri is actually being changed //If the existing Uri is the same as the old one then we change the prefix //but we don't raise the OnNamespaceModified event this._prefixes[hash] = prefix; if (!this._uris[prefix].ToString().Equals(uri.ToString(), StringComparison.Ordinal)) { //Raise modified event this.OnNamespaceModified(prefix, uri); } } } else { //Check whether the Namespace is actually being changed //If the existing Uri is the same as the old one no change is needed if (!this._uris[prefix].ToString().Equals(uri.ToString(), StringComparison.Ordinal)) { //Update the existing Prefix this._uris[prefix] = uri; this._prefixes[hash] = prefix; this.OnNamespaceModified(prefix, uri); } } }
/// <summary> /// Loads Namespaces for the Graph with the given ID into the given Graph object /// </summary> /// <param name="g">Graph to load into</param> /// <param name="graphID">Database Graph ID</param> public override void LoadNamespaces(IGraph g, string graphID) { //Build the SQL for getting the Namespaces String getNamespaces = "SELECT * FROM NAMESPACES N INNER JOIN NS_PREFIXES P ON N.nsPrefixID=P.nsPrefixID INNER JOIN NS_URIS U ON N.nsUriID=U.nsUriID WHERE graphID=" + graphID; //Get the Data this.Open(false); DataTable data = this.ExecuteQuery(getNamespaces); this.Close(false); //Load the Namespace into the Graph String prefix, uri; foreach (DataRow r in data.Rows) { //Get Prefix and Uri from Row prefix = r["nsPrefix"].ToString(); uri = r["nsUri"].ToString(); Uri u = new Uri(uri); //Add to Graph g.NamespaceMap.AddNamespace(prefix, u); //Store the IDs for later if not already stored try { Monitor.Enter(this._nsPrefixIDs); Monitor.Enter(this._nsUriIDs); if (!this._nsPrefixIDs.ContainsKey(prefix)) { this._nsPrefixIDs.Add(prefix, r["nsPrefixID"].ToString()); } if (!this._nsUriIDs.ContainsKey(u.GetEnhancedHashCode())) { this._nsUriIDs.Add(u.GetEnhancedHashCode(), r["nsUriID"].ToString()); } } finally { Monitor.Exit(this._nsPrefixIDs); Monitor.Exit(this._nsUriIDs); } } }
/// <summary> /// Looks up the ID for a Namespace Uri from the Database adding it to the Database if necessary /// </summary> /// <param name="u">Namespace Uri</param> /// <returns></returns> private String GetNSUriID(Uri u) { String uriID; Object id; //Is it in the Dictionary already? if (this._nsUriIDs.ContainsKey(u.GetEnhancedHashCode())) { try { Monitor.Enter(this._nsUriIDs); uriID = this._nsUriIDs[u.GetEnhancedHashCode()]; } finally { Monitor.Exit(this._nsUriIDs); } } else { //Lookup from Database String getUri = "SELECT nsUriID FROM NS_URIS WHERE nsUriHash=" + u.GetEnhancedHashCode(); id = this.ExecuteScalar(getUri); if (id == null) { //Needs adding to Database String addUri = "INSERT INTO NS_URIS (nsUri, nsUriHash) VALUES (N'" + this.EscapeString(u.ToString()) + "', " + u.GetEnhancedHashCode() + ")"; try { this.ExecuteNonQuery(addUri); } catch (SqlException sqlEx) { this.Close(true, true); throw new RdfException("Unable to create a Namespace URI entry in the NS_URIS Table", sqlEx); } //Get the new ID id = this.ExecuteScalar(getUri); if (id == null) { this.Close(true, true); throw new RdfException("Unable to retrieve a required Namespace URI entry from the Database"); } else { uriID = id.ToString(); try { Monitor.Enter(this._nsUriIDs); if (!this._nsUriIDs.ContainsKey(u.GetEnhancedHashCode())) { this._nsUriIDs.Add(u.GetEnhancedHashCode(), uriID); } } finally { Monitor.Exit(this._nsUriIDs); } } } else { uriID = id.ToString(); try { Monitor.Enter(this._nsUriIDs); if (!this._nsUriIDs.ContainsKey(u.GetEnhancedHashCode())) { this._nsUriIDs.Add(u.GetEnhancedHashCode(), uriID); } } finally { Monitor.Exit(this._nsUriIDs); } } } return uriID; }
private void DoUpgrade() { int completed = 0; try { //First run the Upgrade Script //Need to read it in from dotNetRDF assembly StreamReader reader = new StreamReader(Assembly.GetAssembly(typeof(VDS.RDF.Graph)).GetManifestResourceStream("VDS.RDF.Storage.UpgradeMSSQLStore_010_011.sql")); String upgrade = reader.ReadToEnd(); reader.Close(); this._connection.ExecuteNonQuery(upgrade); completed++; this.OnProgress(completed); //Generate Hash Codes for the Graph URIs DataTable graphs = this._connection.ExecuteQuery("SELECT graphID, graphUri FROM GRAPHS"); foreach (DataRow g in graphs.Rows) { Uri graphUri = new Uri(g["graphUri"].ToString()); int graphHash = graphUri.GetEnhancedHashCode(); this._connection.ExecuteNonQuery("UPDATE GRAPHS SET graphHash=" + graphHash + " WHERE graphID=" + g["graphID"].ToString()); completed++; this.OnProgress(completed); } //Generate Hash Codes for the Namespace URIs DataTable namespaces = this._connection.ExecuteQuery("SELECT nsUriID, nsUri FROM NS_URIS"); foreach (DataRow n in namespaces.Rows) { Uri nsUri = new Uri(n["nsUri"].ToString()); int nsUriHash = nsUri.GetEnhancedHashCode(); this._connection.ExecuteNonQuery("UPDATE NS_URIS SET nsUriHash=" + nsUriHash + " WHERE nsUriID=" + n["nsUriID"].ToString()); completed++; this.OnProgress(completed); } //Generate Hash Codes for Nodes DataTable nodes = this._connection.ExecuteQuery("SELECT nodeID, nodeType, nodeValue FROM NODES"); foreach (DataRow n in nodes.Rows) { INode temp = this.DecodeNode(n); this._connection.ExecuteNonQuery("UPDATE NODES SET nodeHash=" + temp.GetHashCode() + " WHERE nodeID=" + n["nodeID"].ToString()); completed++; this.OnProgress(completed); } //Generate Hash Codes for Triples String getTriples = "SELECT * FROM TRIPLES T INNER JOIN NODES S ON T.tripleSubject=S.nodeID INNER JOIN NODES P ON T.triplePredicate=P.nodeID INNER JOIN NODES O ON T.tripleObject=O.nodeID"; DataTable triples = this._connection.ExecuteQuery(getTriples); foreach (DataRow t in triples.Rows) { int tripleHash = (t["nodeHash"].ToString() + t["nodeHash1"].ToString() + t["nodeHash2"].ToString()).GetHashCode(); this._connection.ExecuteNonQuery("UPDATE TRIPLES SET tripleHash=" + tripleHash + " WHERE tripleID=" + t["tripleID"].ToString()); completed++; this.OnProgress(completed); } } catch (Exception ex) { this.OnError(ex); } }