2 using System
.Collections
;
7 public interface StatementSource
{
8 void Select(StatementSink sink
);
11 public interface StatementSink
{
12 bool Add(Statement statement
);
15 internal class StatementCounterSink
: StatementSink
{
18 public int StatementCount { get { return counter; }
}
20 public bool Add(Statement statement
) {
26 internal class StatementExistsSink
: StatementSink
{
29 public bool Exists { get { return exists; }
}
31 public bool Add(Statement statement
) {
37 public abstract class Store
: StatementSource
, StatementSink
{
41 public static StatementSource
CreateForInput(string spec
) {
42 return (StatementSource
)Create(spec
, false);
45 public static StatementSink
CreateForOutput(string spec
) {
46 return (StatementSink
)Create(spec
, true);
49 private static object Create(string spec
, bool output
) {
52 int c
= spec
.IndexOf(':');
54 type
= spec
.Substring(0, c
);
55 spec
= spec
.Substring(c
+1);
62 return new MemoryStore();
64 if (spec
== "") throw new ArgumentException("Use: xml:filename");
66 return new RdfXmlWriter(spec
);
68 return new RdfXmlReader(spec
);
74 if (spec
== "") throw new ArgumentException("Use: format:filename");
76 N3Writer ret
= new N3Writer(spec
);
78 case "nt": case "ntriples":
79 ret
.Format
= N3Writer
.Formats
.NTriples
;
82 ret
.Format
= N3Writer
.Formats
.Turtle
;
87 return new N3Reader(spec
);
91 if (spec
== "") throw new ArgumentException("Use: sqlite|mysql:table:connection-string");
93 c
= spec
.IndexOf(':');
94 if (c
== -1) throw new ArgumentException("Invalid format for sqlite/mysql spec parameter (table:constring).");
95 string table
= spec
.Substring(0, c
);
96 spec
= spec
.Substring(c
+1);
98 string classtype
= null;
99 if (type
== "sqlite") {
100 classtype
= "SemWeb.Stores.SqliteStore, SemWeb.SqliteStore";
101 spec
= spec
.Replace(";", ",");
102 } else if (type
== "mysql") {
103 classtype
= "SemWeb.Stores.MySQLStore, SemWeb.MySQLStore";
105 Type ttype
= Type
.GetType(classtype
);
107 throw new NotSupportedException("The storage type in <" + classtype
+ "> could not be found.");
108 return Activator
.CreateInstance(ttype
, new object[] { spec, table }
);
110 throw new ArgumentException("Unknown parser type: " + type
);
115 rdfType
= new Entity("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
118 public abstract int StatementCount { get; }
120 public abstract void Clear();
122 public Entity
[] GetEntitiesOfType(Entity type
) {
123 ArrayList entities
= new ArrayList();
125 MemoryStore result
= Select(new Statement(null, rdfType
, type
));
126 foreach (Statement s
in result
.Statements
) {
127 entities
.Add(s
.Subject
);
130 return (Entity
[])entities
.ToArray(typeof(Entity
));
133 bool StatementSink
.Add(Statement statement
) {
138 public abstract void Add(Statement statement
);
140 public abstract void Remove(Statement statement
);
142 public virtual void Import(StatementSource source
) {
146 public abstract Entity
[] GetAllEntities();
148 public abstract Entity
[] GetAllPredicates();
150 public virtual bool Contains(Statement statement
) {
151 StatementExistsSink sink
= new StatementExistsSink();
152 SelectPartialFilter filter
= SelectPartialFilter
.All
;
153 filter
.SelectFirst
= true;
154 Select(statement
, filter
, sink
);
158 public void Select(StatementSink result
) {
159 Select(new Statement(null,null,null), result
);
162 public void Select(Statement template
, StatementSink result
) {
163 Select(template
, SelectPartialFilter
.All
, result
);
166 public void Select(Statement
[] templates
, StatementSink result
) {
167 Select(templates
, SelectPartialFilter
.All
, result
);
170 public abstract void Select(Statement template
, SelectPartialFilter partialFilter
, StatementSink result
);
172 public abstract void Select(Statement
[] templates
, SelectPartialFilter partialFilter
, StatementSink result
);
174 public MemoryStore
Select(Statement template
) {
175 return Select(template
, SelectPartialFilter
.All
);
178 public MemoryStore
Select(Statement template
, SelectPartialFilter partialFilter
) {
179 MemoryStore ms
= new MemoryStore();
180 ms
.allowIndexing
= false;
181 Select(template
, partialFilter
, ms
);
185 public MemoryStore
Select(Statement
[] templates
) {
186 return Select(templates
, SelectPartialFilter
.All
);
189 public MemoryStore
Select(Statement
[] templates
, SelectPartialFilter partialFilter
) {
190 MemoryStore ms
= new MemoryStore();
191 ms
.allowIndexing
= false;
192 Select(templates
, partialFilter
, ms
);
196 public Resource
[] SelectObjects(Entity subject
, Entity predicate
) {
197 Hashtable resources
= new Hashtable();
198 foreach (Statement s
in Select(new Statement(subject
, predicate
, null), new SelectPartialFilter(false, false, true, false)))
199 if (!resources
.ContainsKey(s
.Object
))
200 resources
[s
.Object
] = s
.Object
;
201 return (Resource
[])new ArrayList(resources
.Keys
).ToArray(typeof(Resource
));
203 public Entity
[] SelectSubjects(Entity predicate
, Resource
@object) {
204 Hashtable resources
= new Hashtable();
205 foreach (Statement s
in Select(new Statement(null, predicate
, @object), new SelectPartialFilter(true, false, false, false)))
206 if (!resources
.ContainsKey(s
.Subject
))
207 resources
[s
.Subject
] = s
.Subject
;
208 return (Entity
[])new ArrayList(resources
.Keys
).ToArray(typeof(Entity
));
211 public abstract void Replace(Entity find
, Entity replacement
);
213 public abstract void Replace(Statement find
, Statement replacement
);
215 public virtual Entity
[] FindEntities(Statement
[] filters
) {
216 Hashtable ents
= new Hashtable();
217 Select(filters
[0], new FindEntitiesSink(ents
, spom(filters
[0])));
218 for (int i
= 1; i
< filters
.Length
; i
++) {
219 Hashtable ents2
= new Hashtable();
220 Select(filters
[i
], new FindEntitiesSink(ents2
, spom(filters
[i
])));
222 Hashtable ents3
= new Hashtable();
223 if (ents
.Count
< ents2
.Count
) {
224 foreach (Entity r
in ents
.Keys
)
225 if (ents2
.ContainsKey(r
))
228 foreach (Entity r
in ents2
.Keys
)
229 if (ents
.ContainsKey(r
))
235 ArrayList ret
= new ArrayList();
236 ret
.AddRange(ents
.Keys
);
237 return (Entity
[])ret
.ToArray(typeof(Entity
));
240 private int spom(Statement s
) {
241 if (s
.Subject
== null) return 0;
242 if (s
.Predicate
== null) return 1;
243 if (s
.Object
== null) return 2;
244 if (s
.Meta
== null) return 3;
245 throw new InvalidOperationException("A statement did not have a null field.");
248 private class FindEntitiesSink
: StatementSink
{
251 public FindEntitiesSink(Hashtable ents
, int spom
) { this.ents = ents; this.spom = spom; }
252 public bool Add(Statement s
) {
254 if (spom
== 0) e
= s
.Subject
;
255 if (spom
== 1) e
= s
.Predicate
;
256 if (spom
== 2) e
= s
.Object
as Entity
;
257 if (spom
== 3) e
= s
.Meta
;
258 if (e
!= null) ents
[e
] = ents
;
263 public void Write(RdfWriter writer
) {
264 Select(new Statement(null,null,null), writer
);
267 public void Write(System
.IO
.TextWriter writer
) {
268 using (RdfWriter w
= new N3Writer(writer
)) {
273 protected object GetResourceKey(Resource resource
) {
274 return resource
.GetResourceKey(this);
277 protected void SetResourceKey(Resource resource
, object value) {
278 resource
.SetResourceKey(this, value);
284 namespace SemWeb
.Stores
{
286 public class MultiStore
: Store
{
287 ArrayList stores
= new ArrayList();
289 public MultiStore() { }
291 public void Add(Store store
) {
295 public void Add(Store store
, RdfReader source
) {
297 store
.Import(source
);
300 public void Remove(Store store
) {
301 stores
.Remove(store
);
304 public override int StatementCount
{
307 foreach (Store s
in stores
)
308 ret
+= s
.StatementCount
;
313 public override void Clear() {
314 throw new InvalidOperationException("Clear is not a valid operation on a MultiStore.");
317 public override Entity
[] GetAllEntities() {
318 Hashtable h
= new Hashtable();
319 foreach (Store s
in stores
)
320 foreach (Resource r
in s
.GetAllEntities())
322 return (Entity
[])new ArrayList(h
.Keys
).ToArray(typeof(Entity
));
325 public override Entity
[] GetAllPredicates() {
326 Hashtable h
= new Hashtable();
327 foreach (Store s
in stores
)
328 foreach (Resource r
in s
.GetAllPredicates())
330 return (Entity
[])new ArrayList(h
.Keys
).ToArray(typeof(Entity
));
333 public override void Add(Statement statement
) { throw new InvalidOperationException("Add is not a valid operation on a MultiStore."); }
335 public override bool Contains(Statement statement
) {
336 foreach (Store s
in stores
)
337 if (s
.Contains(statement
))
342 public override void Remove(Statement statement
) { throw new InvalidOperationException("Add is not a valid operation on a MultiStore."); }
344 public override void Select(Statement template
, SelectPartialFilter partialFilter
, StatementSink result
) {
345 foreach (Store s
in stores
)
346 s
.Select(template
, partialFilter
, result
);
349 public override void Select(Statement
[] templates
, SelectPartialFilter partialFilter
, StatementSink result
) {
350 foreach (Store s
in stores
)
351 s
.Select(templates
, partialFilter
, result
);
354 public override void Replace(Entity a
, Entity b
) {
355 foreach (Store s
in stores
)
359 public override void Replace(Statement find
, Statement replacement
) {
360 foreach (Store s
in stores
)
361 s
.Replace(find
, replacement
);
364 public override Entity
[] FindEntities(Statement
[] filters
) {
365 Hashtable h
= new Hashtable();
366 foreach (Store s
in stores
)
367 foreach (Entity e
in s
.FindEntities(filters
))
369 return (Entity
[])new ArrayList(h
.Keys
).ToArray(typeof(Entity
));