Logo Search packages:      
Sourcecode: f-spot version File versions

Store.cs

using System;
using System.Collections;
using System.Data;

using SemWeb.Util;

namespace SemWeb {
      
      public interface StatementSource {
            bool Distinct { get; }
            void Select(StatementSink sink);
      }
      
      public interface SelectableSource : StatementSource {
            bool Contains(Statement template);
            void Select(Statement template, StatementSink sink);
            void Select(SelectFilter filter, StatementSink sink);
      }

      public interface QueryableSource : SelectableSource {
            void Query(Statement[] graph, SemWeb.Query.QueryResultSink sink);
            void Query(SelectFilter[] graph, SemWeb.Query.QueryResultSink sink);
      }
      
      public interface StatementSink {
            bool Add(Statement statement);
      }

      public interface ModifiableSource : StatementSink {
            void Clear();
            void Import(StatementSource source);
            void Remove(Statement template);
            void RemoveAll(Statement[] templates);
            void Replace(Entity find, Entity replacement);
            void Replace(Statement find, Statement replacement);
      }
      
      internal class StatementCounterSink : StatementSink {
            int counter = 0;
            
            public int StatementCount { get { return counter; } }
            
            public bool Add(Statement statement) {
                  counter++;
                  return true;
            }
      }

      internal class StatementExistsSink : StatementSink {
            bool exists = false;
            
            public bool Exists { get { return exists; } }
            
            public bool Add(Statement statement) {
                  exists = true;
                  return false;
            }
      }

      public abstract class Store : StatementSource, StatementSink,
            SelectableSource, ModifiableSource,
            IDisposable {
            
            Entity rdfType;
            
            public static StatementSource CreateForInput(string spec) {
                  if (spec.StartsWith("rdfs+")) {
                        StatementSource s = CreateForInput(spec.Substring(5));
                        if (!(s is SelectableSource)) s = new MemoryStore(s);
                        return new SemWeb.Inference.RDFS(s, (SelectableSource)s);
                  }
                  return (StatementSource)Create(spec, false);
            }           
            
            public static StatementSink CreateForOutput(string spec) {
                  return (StatementSink)Create(spec, true);
            }
            
            private static object Create(string spec, bool output) {
                  string[] multispecs = spec.Split('\n', '|');
                  if (multispecs.Length > 1) {
                        SemWeb.Stores.MultiStore multistore = new SemWeb.Stores.MultiStore();
                        foreach (string mspec in multispecs) {
                              object mstore = Create(mspec.Trim(), output);
                              if (mstore is SelectableSource) {
                                    multistore.Add((SelectableSource)mstore);
                              } else if (mstore is StatementSource) {
                                    MemoryStore m = new MemoryStore((StatementSource)mstore);
                                    multistore.Add(m);
                              }
                        }
                        return multistore;
                  }
            
                  string type = spec;
                  
                  int c = spec.IndexOf(':');
                  if (c != -1) {
                        type = spec.Substring(0, c);
                        spec = spec.Substring(c+1);
                  } else {
                        spec = "";
                  }
                  
                  Type ttype;
                  
                  switch (type) {
                        case "mem":
                              return new MemoryStore();
                        case "xml":
                              if (spec == "") throw new ArgumentException("Use: xml:filename");
                              if (output) {
                                    return new RdfXmlWriter(spec);
                              } else {
                                    return new RdfXmlReader(spec);
                              }
                        case "n3":
                        case "ntriples":
                        case "nt":
                        case "turtle":
                              if (spec == "") throw new ArgumentException("Use: format:filename");
                              if (output) {
                                    N3Writer ret = new N3Writer(spec); // turtle is default format
                                    switch (type) {
                                          case "nt": case "ntriples":
                                                ret.Format = N3Writer.Formats.NTriples;
                                                break;
                                    }
                                    return ret;
                              } else {
                                    return new N3Reader(spec);
                              }
                        /*case "file":
                              if (spec == "") throw new ArgumentException("Use: format:filename");
                              if (output) throw new ArgumentException("The FileStore does not support writing.");
                              return new SemWeb.Stores.FileStore(spec);*/
                        case "sqlite":
                        case "mysql":
                        case "postgresql":
                              if (spec == "") throw new ArgumentException("Use: sqlite|mysql|postgresql:table:connection-string");
                        
                              c = spec.IndexOf(':');
                              if (c == -1) throw new ArgumentException("Invalid format for SQL spec parameter (table:constring).");
                              string table = spec.Substring(0, c);
                              spec = spec.Substring(c+1);
                              
                              string classtype = null;
                              if (type == "sqlite") {
                                    classtype = "SemWeb.Stores.SqliteStore, SemWeb.SqliteStore";
                                    spec = spec.Replace(";", ",");
                              } else if (type == "mysql") {
                                    classtype = "SemWeb.Stores.MySQLStore, SemWeb.MySQLStore";
                              } else if (type == "postgresql") {
                                    classtype = "SemWeb.Stores.PostgreSQLStore, SemWeb.PostgreSQLStore";
                              }
                              ttype = Type.GetType(classtype);
                              if (ttype == null)
                                    throw new NotSupportedException("The storage type in <" + classtype + "> could not be found.");
                              return Activator.CreateInstance(ttype, new object[] { spec, table });
                        /*case "bdb":
                              return new SemWeb.Stores.BDBStore(spec);*/
                        case "sparql-http":
                              return new SemWeb.Remote.SparqlHttpSource(spec);
                        case "class":
                              ttype = Type.GetType(spec);
                              if (ttype == null)
                                    throw new NotSupportedException("The class <" + spec + "> could not be found.");
                              return Activator.CreateInstance(ttype);
                        default:
                              throw new ArgumentException("Unknown parser type: " + type);
                  }
            }
            
            protected Store() {
                  rdfType = new Entity("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
            }
            
            void IDisposable.Dispose() {
                  Close();
            }
            
            public virtual void Close() {
            }
            
            public abstract bool Distinct { get; }
            
            public abstract int StatementCount { get; }

            public abstract void Clear();

            public Entity[] GetEntitiesOfType(Entity type) {
                  ArrayList entities = new ArrayList();
                  
                  IEnumerable result = Select(new Statement(null, rdfType, type));
                  foreach (Statement s in result) {
                        entities.Add(s.Subject);
                  }
                  
                  return (Entity[])entities.ToArray(typeof(Entity));
            }
            
            bool StatementSink.Add(Statement statement) {
                  Add(statement);
                  return true;
            }
            
            public abstract void Add(Statement statement);
            
            public abstract void Remove(Statement statement);

            public virtual void Import(StatementSource source) {
                  source.Select(this);
            }
            
            public void RemoveAll(Statement[] templates) {
                  foreach (Statement t in templates)
                        Remove(t);
            }
            
            public abstract Entity[] GetEntities();
            
            public abstract Entity[] GetPredicates();
            
            public abstract Entity[] GetMetas();
            
            public virtual bool Contains(Statement template) {
                  return DefaultContains(this, template);
            }

            public static bool DefaultContains(SelectableSource source, Statement template) {
                  StatementExistsSink sink = new StatementExistsSink();
                  SelectFilter filter = new SelectFilter(template);
                  filter.Limit = 1;
                  source.Select(filter, sink);
                  return sink.Exists;
            }
            
            public static void DefaultSelect(SelectableSource source, SelectFilter filter, StatementSink sink) {
                  // This method should be avoided...
                  if (filter.LiteralFilters != null)
                        sink = new SemWeb.Filters.FilterSink(filter.LiteralFilters, sink, source);
                  foreach (Entity subject in filter.Subjects == null ? new Entity[] { null } : filter.Subjects)
                  foreach (Entity predicate in filter.Predicates == null ? new Entity[] { null } : filter.Predicates)
                  foreach (Resource objct in filter.Objects == null ? new Resource[] { null } : filter.Objects)
                  foreach (Entity meta in filter.Metas == null ? new Entity[] { null } : filter.Metas)
                        source.Select(new Statement(subject, predicate, objct, meta), sink);
            }           
            
            public void Select(StatementSink result) {
                  Select(Statement.All, result);
            }
            
            public abstract void Select(Statement template, StatementSink result);
            
            public abstract void Select(SelectFilter filter, StatementSink result);
            
            public SelectResult Select(Statement template) {
                  return new SelectResult.Single(this, template);
            }
            
            public SelectResult Select(SelectFilter filter) {
                  return new SelectResult.Multi(this, filter);
            }
            
            public Resource[] SelectObjects(Entity subject, Entity predicate) {
                  Hashtable resources = new Hashtable();
                  ResourceCollector collector = new ResourceCollector();
                  collector.SPO = 2;
                  collector.Table = resources;
                  Select(new Statement(subject, predicate, null, null), collector);
                  return (Resource[])new ArrayList(resources.Keys).ToArray(typeof(Resource));
            }
            public Entity[] SelectSubjects(Entity predicate, Resource @object) {
                  Hashtable resources = new Hashtable();
                  ResourceCollector collector = new ResourceCollector();
                  collector.SPO = 0;
                  collector.Table = resources;
                  Select(new Statement(null, predicate, @object, null), collector);
                  return (Entity[])new ArrayList(resources.Keys).ToArray(typeof(Entity));
            }
            class ResourceCollector : StatementSink {
                  public Hashtable Table;
                  public int SPO;
                  public bool Add(Statement s) {
                        if (SPO == 0) Table[s.Subject] = Table;
                        if (SPO == 2) Table[s.Object] = Table;
                        return true;
                  }
            }
            
            public virtual void Replace(Entity find, Entity replacement) {
                  MemoryStore deletions = new MemoryStore();
                  MemoryStore additions = new MemoryStore();
                  
                  Select(new Statement(find, null, null, null), deletions);
                  Select(new Statement(null, find, null, null), deletions);
                  Select(new Statement(null, null, find, null), deletions);
                  Select(new Statement(null, null, null, find), deletions);
                  
                  foreach (Statement s in deletions) {
                        Remove(s);
                        additions.Add(s.Replace(find, replacement));
                  }
                  
                  foreach (Statement s in additions) {
                        Add(s);
                  }
            }
            
            public virtual void Replace(Statement find, Statement replacement) {
                  Remove(find);
                  Add(replacement);
            }
            
            public void Write(System.IO.TextWriter writer) {
                  using (RdfWriter w = new N3Writer(writer)) {
                        Select(w);
                  }
            }
            
            protected object GetResourceKey(Resource resource) {
                  return resource.GetResourceKey(this);
            }

            protected void SetResourceKey(Resource resource, object value) {
                  resource.SetResourceKey(this, value);
            }
            
      }

      public abstract class SelectResult : StatementSource, IEnumerable {
            internal Store source;
            MemoryStore ms;
            internal SelectResult(Store source) { this.source = source; }
            public bool Distinct { get { return source.Distinct; } }
            public abstract void Select(StatementSink sink);
            public IEnumerator GetEnumerator() {
                  return Buffer().Statements.GetEnumerator();
            }
            public long StatementCount { get { return Buffer().StatementCount; } }
            public MemoryStore Load() { return Buffer(); }
            public Statement[] ToArray() { return Load().ToArray(); }
            private MemoryStore Buffer() {
                  if (ms != null) return ms;
                  ms = new MemoryStore();
                  ms.allowIndexing = false;
                  Select(ms);
                  return ms;
            }
            
            internal class Single : SelectResult {
                  Statement template;
                  public Single(Store source, Statement template) : base(source) {
                        this.template = template;
                  }
                  public override void Select(StatementSink sink) {
                        source.Select(template, sink);
                  }
            }
            
            internal class Multi : SelectResult {
                  SelectFilter filter;
                  public Multi(Store source, SelectFilter filter)
                        : base(source) {
                        this.filter = filter;
                  }
                  public override void Select(StatementSink sink) {
                        source.Select(filter, sink);
                  }
            }
      }
}

namespace SemWeb.Stores {

      public interface SupportsPersistableBNodes {
            string GetStoreGuid();
            string GetNodeId(BNode node);
            BNode GetNodeFromId(string persistentId);
      }

      public class MultiStore : Store {
            ArrayList stores = new ArrayList();
            Hashtable namedgraphs = new Hashtable();
            ArrayList allsources = new ArrayList();
            
            public MultiStore() { }
            
            public override bool Distinct { get { return false; } }
            
            public void Add(SelectableSource store) {
                  stores.Add(store);
                  allsources.Add(store);
            }
            
            public void Add(string uri, SelectableSource store) {
                  namedgraphs[uri] = store;
                  allsources.Add(store);
            }
            
            public void Add(RdfReader source) {
                  MemoryStore store = new MemoryStore(source);
                  Add(store);
            }
            
            public void Add(string uri, RdfReader source) {
                  MemoryStore store = new MemoryStore(source);
                  Add(uri, store);
            }
            
            public void Remove(SelectableSource store) {
                  stores.Remove(store);
                  allsources.Remove(store);
            }
            
            public void Remove(string uri) {
                  allsources.Remove(namedgraphs[uri]);
                  namedgraphs.Remove(uri);
            }
            
            public override int StatementCount {
                  get {
                        int ret = 0;
                        foreach (StatementSource s in allsources) {
                              if (s is Store)
                                    ret += ((Store)s).StatementCount;
                              else
                                    throw new InvalidOperationException("Not all sources are stores supporting StatementCount.");
                        }
                        return ret;
                  }
            }

            public override void Clear() {
                  throw new InvalidOperationException("Clear is not a valid operation on a MultiStore.");
            }
            
            public override Entity[] GetEntities() {
                  Hashtable h = new Hashtable();
                  foreach (StatementSource s in allsources) {
                        if (s is Store) {
                              foreach (Resource r in ((Store)s).GetEntities())
                                    h[r] = h;
                        } else {
                              throw new InvalidOperationException("Not all sources are stores supporting GetEntities.");
                        }
                  }
                  return (Entity[])new ArrayList(h.Keys).ToArray(typeof(Entity));
            }
            
            public override Entity[] GetPredicates() {
                  Hashtable h = new Hashtable();
                  foreach (StatementSource s in allsources) {
                        if (s is Store) {
                              foreach (Resource r in ((Store)s).GetPredicates())
                                    h[r] = h;
                        } else {
                              throw new InvalidOperationException("Not all sources are stores supporting GetEntities.");
                        }
                  }
                  return (Entity[])new ArrayList(h.Keys).ToArray(typeof(Entity));
            }

            public override Entity[] GetMetas() {
                  Hashtable h = new Hashtable();
                  foreach (StatementSource s in allsources) {
                        if (s is Store) {
                              foreach (Resource r in ((Store)s).GetMetas())
                                    h[r] = h;
                        } else {
                              throw new InvalidOperationException("Not all sources are stores supporting GetEntities.");
                        }
                  }
                  return (Entity[])new ArrayList(h.Keys).ToArray(typeof(Entity));
            }

            public override void Add(Statement statement) { throw new InvalidOperationException("Add is not a valid operation on a MultiStore."); }
            
            SelectableSource[] GetSources(Entity graph) {
                  if (graph == null || namedgraphs.Count == 0)
                        return (SelectableSource[])allsources.ToArray(typeof(SelectableSource));
                  else if (graph == Statement.DefaultMeta)
                        return (SelectableSource[])stores.ToArray(typeof(SelectableSource));
                  else if (graph.Uri != null && namedgraphs.ContainsKey(graph.Uri))
                        return new SelectableSource[] { (SelectableSource)namedgraphs[graph.Uri] };
                  else
                        return null;
            }
            
            public override bool Contains(Statement statement) {
                  SelectableSource[] sources = GetSources(statement.Meta);
                  if (sources == null) return false;
                  foreach (SelectableSource s in sources)
                        if (s.Contains(statement))
                              return true;
                  return false;
            }
                  
            public override void Remove(Statement statement) { throw new InvalidOperationException("Remove is not a valid operation on a MultiStore."); }
            
            public override void Select(Statement template, StatementSink result) {
                  SelectableSource[] sources = GetSources(template.Meta);
                  if (sources == null) return;
                  template.Meta = null;
                  foreach (SelectableSource s in sources)
                        s.Select(template, result);
            }
            
            public override void Select(SelectFilter filter, StatementSink result) {
                  Entity[] scanMetas = filter.Metas;
                  filter.Metas = null;
                  if (scanMetas == null || namedgraphs.Count == 0) scanMetas = new Entity[] { null };
                  foreach (Entity meta in scanMetas) {
                        SelectableSource[] sources = GetSources(meta);
                        if (sources == null) continue;
                        foreach (SelectableSource s in sources)
                              s.Select(filter, result);
                  }
            }

            public override void Replace(Entity a, Entity b) { throw new InvalidOperationException("Replace is not a valid operation on a MultiStore."); }
            
            public override void Replace(Statement find, Statement replacement) { throw new InvalidOperationException("Replace is not a valid operation on a MultiStore."); }
            
      }
      
      public abstract class SimpleSourceWrapper : SelectableSource {
      
            public virtual bool Distinct { get { return true; } }
            
            public virtual void Select(StatementSink sink) {
                  // The default implementation does not return
                  // anything for this call.
            }

            public virtual bool Contains(Statement template) {
                  template.Object = null; // reduce to another case (else there would be recursion)
                  return Store.DefaultContains(this, template);
            }
            
            protected virtual void SelectAllSubject(Entity subject, StatementSink sink) {
            }

            protected virtual void SelectAllObject(Resource @object, StatementSink sink) {
            }

            protected virtual void SelectRelationsBetween(Entity subject, Resource @object, StatementSink sink) {
            }
            
            protected virtual void SelectAllPairs(Entity predicate, StatementSink sink) {
            }

            protected virtual void SelectSubjects(Entity predicate, Resource @object, StatementSink sink) {
            }

            protected virtual void SelectObjects(Entity subject, Entity predicate, StatementSink sink) {
            }

            public void Select(Statement template, StatementSink sink) {
                  if (template.Meta != null && template.Meta != Statement.DefaultMeta) return;
                  if (template.Predicate != null && template.Predicate.Uri == null) return;
                  
                  if (template.Subject == null && template.Predicate == null && template.Object == null) {
                        Select(sink);
                  } else if (template.Subject != null && template.Predicate != null && template.Object != null) {
                        template.Meta = Statement.DefaultMeta;
                        if (Contains(template))
                              sink.Add(template);
                  } else if (template.Predicate == null) {
                        if (template.Subject == null)
                              SelectAllObject(template.Object, sink); 
                        else if (template.Object == null)
                              SelectAllSubject(template.Subject, sink); 
                        else
                              SelectRelationsBetween(template.Subject, template.Object, sink);
                  } else if (template.Subject != null && template.Object == null) {
                        SelectObjects(template.Subject, template.Predicate, sink);
                  } else if (template.Subject == null && template.Object != null) {
                        SelectSubjects(template.Predicate, template.Object, sink);
                  } else if (template.Subject == null && template.Object == null) {
                        SelectAllPairs(template.Predicate, sink);
                  }
            }
      
            public void Select(SelectFilter filter, StatementSink sink) {
                  Store.DefaultSelect(this, filter, sink);
            }
      }
      
      public class DebuggedSource : SelectableSource {
            SelectableSource source;
            System.IO.TextWriter output;
            
            public DebuggedSource(SelectableSource source, System.IO.TextWriter output) {
                  this.source = source;
                  this.output = output;
            }
            
            public bool Distinct { get { return source.Distinct; } }
            
            public void Select(StatementSink sink) {
                  Select(Statement.All, sink);
            }

            public bool Contains(Statement template) {
                  output.WriteLine("CONTAINS: " + template);
                  return source.Contains(template);
            }
            
            public void Select(Statement template, StatementSink sink) {
                  output.WriteLine("SELECT: " + template);
                  source.Select(template, sink);
            }
      
            public void Select(SelectFilter filter, StatementSink sink) {
                  output.WriteLine("SELECT: " + filter);
                  source.Select(filter, sink);
            }
      }
      
      public class CachedSource : SelectableSource {
            SelectableSource source;

            StatementMap containsresults = new StatementMap();
            StatementMap selectresults = new StatementMap();
            Hashtable selfilterresults = new Hashtable();
      
            public CachedSource(SelectableSource s) { source = s; }
      
            public bool Distinct { get { return source.Distinct; } }
            
            public void Select(StatementSink sink) {
                  Select(Statement.All, sink);
            }

            public bool Contains(Statement template) {
                  if (!containsresults.ContainsKey(template))
                        containsresults[template] = source.Contains(template);
                  return (bool)containsresults[template];
            }
            
            public void Select(Statement template, StatementSink sink) {
                  if (!selectresults.ContainsKey(template)) {
                        MemoryStore s = new MemoryStore();
                        source.Select(template, s);
                        selectresults[template] = s;
                  }
                  ((MemoryStore)selectresults[template]).Select(sink);
            }
      
            public void Select(SelectFilter filter, StatementSink sink) {
                  if (!selfilterresults.ContainsKey(filter)) {
                        MemoryStore s = new MemoryStore();
                        source.Select(filter, s);
                        selfilterresults[filter] = s;
                  }
                  ((MemoryStore)selfilterresults[filter]).Select(sink);
            }

      }
}

Generated by  Doxygen 1.6.0   Back to index