private void Select(Resource templateSubject, Resource templatePredicate, Resource templateObject, Resource templateMeta, LiteralFilter[] litFilters, StatementSink result, int limit) {
			if (result == null) throw new ArgumentNullException();
	
			lock (syncroot) {
			
			Init();
			RunAddBuffer();
			
			// Don't select on columns that we already know from the template.
			// But grab the URIs and literal values for MultiRes selection.
			SelectColumnFilter columns = new SelectColumnFilter();
			columns.SubjectId = (templateSubject == null) || templateSubject is MultiRes;
			columns.PredicateId = (templatePredicate == null) || templatePredicate is MultiRes;
			columns.ObjectId = (templateObject == null) || templateObject is MultiRes;
			columns.MetaId = (templateMeta == null) || templateMeta is MultiRes;
			columns.SubjectUri = templateSubject == null;
			columns.PredicateUri = templatePredicate == null;
			columns.ObjectData = templateObject == null || (templateObject is MultiRes && ((MultiRes)templateObject).ContainsLiterals());
			columns.MetaUri = templateMeta == null;
			
			if (isOrContains(templatePredicate, rdfs_member)) {
				columns.PredicateId = true;
				columns.PredicateUri = true;
			}
			
			// Meta URIs tend to be repeated a lot, so we don't
			// want to ever select them from the database.
			// This preloads them, although it makes the first
			// select quite slow.
			/*if (templateMeta == null && SupportsSubquery) {
				LoadMetaEntities();
				columns.MetaUri = false;
			}*/
			
			// Have to select something
			bool fakeSubjectIdSelect = false;
			if (!columns.SubjectId && !columns.PredicateId && !columns.ObjectId && !columns.MetaId) {
				columns.SubjectId = true;
				fakeSubjectIdSelect = true;
			}
				
			// Pre-cache the IDs of resources in a MultiRes. TODO: Pool these into one array.
			foreach (Resource r in new Resource[] { templateSubject, templatePredicate, templateObject, templateMeta }) {
				MultiRes mr = r as MultiRes;
				if (mr == null) continue;
				PrefetchResourceIds(mr.items);
				CleanMultiRes(mr);
				if (mr.items.Length == 0) // no possible values
					return;
			}
				
			// SQLite has a problem with LEFT JOIN: When a condition is made on the
			// first table in the ON clause (q.objecttype=0/1), when it fails,
			// it excludes the row from the first table, whereas it should only
			// exclude the results of the join.
						
			System.Text.StringBuilder cmd = new System.Text.StringBuilder("SELECT ");
			if (!SupportsLimitClause && limit >= 1) {
				cmd.Append("TOP ");
				cmd.Append(limit);
				cmd.Append(' ');
			}
			if (!HasUniqueStatementsConstraint)
				cmd.Append("DISTINCT ");
			SelectFilterColumns(columns, cmd);
			cmd.Append(" FROM ");
			cmd.Append(table);
			cmd.Append("_statements AS q");
			SelectFilterTables(columns, cmd);
			cmd.Append(' ');
			
			bool wroteWhere;
			if (!WhereClause(templateSubject, templatePredicate, templateObject, templateMeta, cmd, out wroteWhere)) return;
			
			// Transform literal filters into SQL.
			if (litFilters != null) {
				foreach (LiteralFilter f in litFilters) {
					string s = FilterToSQL(f, "lit.value");
					if (s != null) {
						if (!wroteWhere) { cmd.Append(" WHERE "); wroteWhere = true; }
						else { cmd.Append(" AND "); }
						cmd.Append(' ');
						cmd.Append(s);
					}
				}
			}
			
			if (SupportsLimitClause && limit >= 1) {
				cmd.Append(" LIMIT ");
				cmd.Append(limit);
			}

			cmd.Append(';');
			
			if (Debug) {
				string cmd2 = cmd.ToString();
				//if (cmd2.Length > 80) cmd2 = cmd2.Substring(0, 80);
				Console.Error.WriteLine(cmd2);
			}
			
			Hashtable entMap = new Hashtable();
			
			// Be sure if a MultiRes is involved we hash the
			// ids of the entities so we can return them
			// without creating new ones.
			CacheMultiObjects(entMap, templateSubject);
			CacheMultiObjects(entMap, templatePredicate);
			CacheMultiObjects(entMap, templateObject);
			CacheMultiObjects(entMap, templateMeta);
			
			using (IDataReader reader = RunReader(cmd.ToString())) {
				while (reader.Read()) {
					int col = 0;
                    Int64 sid = -1, pid = -1, ot = -1, oid = -1, mid = -1;
					string suri = null, puri = null, ouri = null, muri = null;
					string lv = null, ll = null, ld = null;
					
					if (columns.SubjectId) { sid = reader.GetInt64(col++); }
					if (columns.PredicateId) { pid = reader.GetInt64(col++); }
					if (columns.ObjectId) { oid = reader.GetInt64(col++); }
					if (columns.MetaId) { mid = reader.GetInt64(col++); }
					
					if (columns.SubjectUri) { suri = AsString(reader[col++]); }
					if (columns.PredicateUri) { puri = AsString(reader[col++]); }
					if (columns.ObjectData) { ot = reader.GetInt64(col++); ouri = AsString(reader[col++]); lv = AsString(reader[col++]); ll = AsString(reader[col++]); ld = AsString(reader[col++]);}
					if (columns.MetaUri) { muri = AsString(reader[col++]); }
					
					Entity subject = GetSelectedEntity(sid, suri, templateSubject, columns.SubjectId && !fakeSubjectIdSelect, columns.SubjectUri, entMap);
					Entity predicate = GetSelectedEntity(pid, puri, templatePredicate, columns.PredicateId, columns.PredicateUri, entMap);
					Resource objec = GetSelectedResource(oid, ot, ouri, lv, ll, ld, templateObject, columns.ObjectId, columns.ObjectData, entMap);
					Entity meta = GetSelectedEntity(mid, muri, templateMeta, columns.MetaId, columns.MetaUri, templateMeta != null ? entMap : null);

					if (litFilters != null && !LiteralFilter.MatchesFilters(objec, litFilters, this))
						continue;
						
					bool ret = result.Add(new Statement(subject, predicate, objec, meta));
					if (!ret) break;
				}
			}
			
			} // lock
		}
		private void SelectFilterTables(SelectColumnFilter filter, StringBuilder cmd) {
			if (filter.SubjectUri) {
				cmd.Append(" LEFT JOIN ");
				cmd.Append(table);
				cmd.Append("_entities AS suri ON q.subject = suri.id");
			}
			if (filter.PredicateUri) {
				cmd.Append(" LEFT JOIN ");
				cmd.Append(table);
				cmd.Append("_entities AS puri ON q.predicate = puri.id");
			}
			if (filter.ObjectData) {
				cmd.Append(" LEFT JOIN ");
				cmd.Append(table);
				cmd.Append("_entities AS ouri ON q.object = ouri.id");

				cmd.Append(" LEFT JOIN ");
				cmd.Append(table);
				cmd.Append("_literals AS lit ON q.object=lit.id");
			}
			if (filter.MetaUri) {
				cmd.Append(" LEFT JOIN ");
				cmd.Append(table);
				cmd.Append("_entities AS muri ON q.meta = muri.id");
			}
		}
Exemple #3
0
        private void Select2(SelectFilter filter, StatementSink result)
        {
            // Don't select on columns that we already know from the template.
            SelectColumnFilter columns = new SelectColumnFilter();

            columns.Subject   = (filter.Subjects == null) || (filter.Subjects.Length > 1);
            columns.Predicate = (filter.Predicates == null) || (filter.Predicates.Length > 1);
            columns.Object    = (filter.Objects == null) || (filter.Objects.Length > 1);
            columns.Meta      = (filter.Metas == null) || (filter.Metas.Length > 1);;

            if (filter.Predicates != null | Array.IndexOf(filter.Predicates, rdfs_member) != 1)
            {
                columns.Predicate = true;
            }

            // Have to select something
            if (!columns.Subject && !columns.Predicate && !columns.Object && !columns.Meta)
            {
                columns.Subject = true;
            }

            System.Text.StringBuilder cmd = new System.Text.StringBuilder("SELECT ");
            if (!connection.AreStatementsUnique)
            {
                cmd.Append("DISTINCT ");
            }

            ArrayList cols = new ArrayList();

            if (columns.Subject)
            {
                cols.Add("sinfo.type"); cols.Add("sinfo.value");
            }
            if (columns.Predicate)
            {
                cols.Add("pinfo.type"); cols.Add("pinfo.value");
            }
            if (columns.Object)
            {
                cols.Add("oinfo.type"); cols.Add("oinfo.value"); cols.Add("oinfo.language"); cols.Add("oinfo.datatype");
            }
            if (columns.Meta)
            {
                cols.Add("minfo.type"); cols.Add("minfo.value");
            }
            cmd.Append(String.Join(", ", (String[])cols.ToArray(typeof(String))));

            cmd.Append(" FROM ");
            cmd.Append(prefix);
            cmd.Append("_statements AS q");

            if (columns.Subject)
            {
                cmd.Append(" LEFT JOIN ");
                cmd.Append(prefix);
                cmd.Append("_values AS sinfo ON q.subject = sinfo.id");
            }
            if (columns.Predicate)
            {
                cmd.Append(" LEFT JOIN ");
                cmd.Append(prefix);
                cmd.Append("_values AS pinfo ON q.predicate = pinfo.id");
            }
            if (columns.Object)
            {
                cmd.Append(" LEFT JOIN ");
                cmd.Append(prefix);
                cmd.Append("_values AS oinfo ON q.object = oinfo.id");
            }
            if (columns.Meta)
            {
                cmd.Append(" LEFT JOIN ");
                cmd.Append(prefix);
                cmd.Append("_values AS minfo ON q.meta = minfo.id");
            }

            cmd.Append(' ');

            bool wroteWhere = WhereClause(filter, cmd);

            // Transform literal filters into SQL.
            if (filter.LiteralFilters != null)
            {
                foreach (LiteralFilter f in filter.LiteralFilters)
                {
                    string s = FilterToSQL(f, "oinfo.value");
                    if (s != null)
                    {
                        if (!wroteWhere)
                        {
                            cmd.Append(" WHERE "); wroteWhere = true;
                        }
                        else
                        {
                            cmd.Append(" AND ");
                        }
                        cmd.Append(' ');
                        cmd.Append(s);
                    }
                }
            }

            if (filter.Limit >= 1)
            {
                cmd.Append(" LIMIT ");
                cmd.Append(filter.Limit);
            }

            cmd.Append(';');

            if (Debug)
            {
                string cmd2 = cmd.ToString();
                //if (cmd2.Length > 80) cmd2 = cmd2.Substring(0, 80);
                Console.Error.WriteLine(cmd2);
            }

            using (IDataReader reader = connection.RunReader(cmd.ToString())) {
                while (reader.Read())
                {
                    Entity   s = columns.Subject ? null : filter.Subjects[0];
                    Entity   p = columns.Predicate ? null : filter.Predicates[0];
                    Resource o = columns.Object ? null : filter.Objects[0];
                    Entity   m = columns.Meta ? null : filter.Metas[0];

                    int col = 0;
                    if (columns.Subject)
                    {
                        s = SelectEntity(reader.GetInt32(col++), reader.GetString(col++));
                    }
                    if (columns.Predicate)
                    {
                        p = SelectEntity(reader.GetInt32(col++), reader.GetString(col++));
                    }
                    if (columns.Object)
                    {
                        o = SelectResource(reader.GetInt32(col++), reader.GetString(col++), reader.GetString(col++), reader.GetString(col++));
                    }
                    if (columns.Meta)
                    {
                        m = SelectEntity(reader.GetInt32(col++), reader.GetString(col++));
                    }

                    if (filter.LiteralFilters != null && !LiteralFilter.MatchesFilters(o, filter.LiteralFilters, this))
                    {
                        continue;
                    }

                    bool ret = result.Add(new Statement(s, p, o, m));
                    if (!ret)
                    {
                        break;
                    }
                }
            }
        }
		private static void SelectFilterColumns(SelectColumnFilter filter, StringBuilder cmd) {
			bool f = true;
			
			if (filter.SubjectId) { cmd.Append("q.subject"); f = false; }
			if (filter.PredicateId) { AppendComma(cmd, "q.predicate", !f); f = false; }
			if (filter.ObjectId) { AppendComma(cmd, "q.object", !f); f = false; }
			if (filter.MetaId) { AppendComma(cmd, "q.meta", !f); f = false; }
			if (filter.SubjectUri) { AppendComma(cmd, "suri.value", !f); f = false; }
			if (filter.PredicateUri) { AppendComma(cmd, "puri.value", !f); f = false; }
			if (filter.ObjectData) { AppendComma(cmd, "q.objecttype, ouri.value, lit.value, lit.language, lit.datatype", !f); f = false; }
			if (filter.MetaUri) { AppendComma(cmd, "muri.value", !f); f = false; }
		}
Exemple #5
0
        private void Select2(SelectFilter filter, StatementSink result)
        {
            // Don't select on columns that we already know from the template.
            SelectColumnFilter columns = new SelectColumnFilter();
            columns.Subject = (filter.Subjects == null) || (filter.Subjects.Length > 1);
            columns.Predicate = (filter.Predicates == null) || (filter.Predicates.Length > 1);
            columns.Object = (filter.Objects == null) || (filter.Objects.Length > 1);
            columns.Meta = (filter.Metas == null) || (filter.Metas.Length > 1);;

            if (filter.Predicates != null | Array.IndexOf(filter.Predicates, rdfs_member) != 1)
                columns.Predicate = true;

            // Have to select something
            if (!columns.Subject && !columns.Predicate && !columns.Object && !columns.Meta)
                columns.Subject = true;

            System.Text.StringBuilder cmd = new System.Text.StringBuilder("SELECT ");
            if (!connection.AreStatementsUnique)
                cmd.Append("DISTINCT ");

            ArrayList cols = new ArrayList();
            if (columns.Subject) { cols.Add("sinfo.type"); cols.Add("sinfo.value"); }
            if (columns.Predicate) { cols.Add("pinfo.type"); cols.Add("pinfo.value"); }
            if (columns.Object) { cols.Add("oinfo.type"); cols.Add("oinfo.value"); cols.Add("oinfo.language"); cols.Add("oinfo.datatype"); }
            if (columns.Meta) { cols.Add("minfo.type"); cols.Add("minfo.value"); }
            cmd.Append(String.Join(", ", (String[])cols.ToArray(typeof(String))));

            cmd.Append(" FROM ");
            cmd.Append(prefix);
            cmd.Append("_statements AS q");

            if (columns.Subject) {
                cmd.Append(" LEFT JOIN ");
                cmd.Append(prefix);
                cmd.Append("_values AS sinfo ON q.subject = sinfo.id");
            }
            if (columns.Predicate) {
                cmd.Append(" LEFT JOIN ");
                cmd.Append(prefix);
                cmd.Append("_values AS pinfo ON q.predicate = pinfo.id");
            }
            if (columns.Object) {
                cmd.Append(" LEFT JOIN ");
                cmd.Append(prefix);
                cmd.Append("_values AS oinfo ON q.object = oinfo.id");
            }
            if (columns.Meta) {
                cmd.Append(" LEFT JOIN ");
                cmd.Append(prefix);
                cmd.Append("_values AS minfo ON q.meta = minfo.id");
            }

            cmd.Append(' ');

            bool wroteWhere = WhereClause(filter, cmd);

            // Transform literal filters into SQL.
            if (filter.LiteralFilters != null) {
                foreach (LiteralFilter f in filter.LiteralFilters) {
                    string s = FilterToSQL(f, "oinfo.value");
                    if (s != null) {
                        if (!wroteWhere) { cmd.Append(" WHERE "); wroteWhere = true; }
                        else { cmd.Append(" AND "); }
                        cmd.Append(' ');
                        cmd.Append(s);
                    }
                }
            }

            if (filter.Limit >= 1) {
                cmd.Append(" LIMIT ");
                cmd.Append(filter.Limit);
            }

            cmd.Append(';');

            if (Debug) {
                string cmd2 = cmd.ToString();
                //if (cmd2.Length > 80) cmd2 = cmd2.Substring(0, 80);
                Console.Error.WriteLine(cmd2);
            }

            using (IDataReader reader = connection.RunReader(cmd.ToString())) {
                while (reader.Read()) {
                    Entity s = columns.Subject ? null : filter.Subjects[0];
                    Entity p = columns.Predicate ? null : filter.Predicates[0];
                    Resource o = columns.Object ? null : filter.Objects[0];
                    Entity m = columns.Meta ? null : filter.Metas[0];

                    int col = 0;
                    if (columns.Subject) { s = SelectEntity(reader.GetInt32(col++), reader.GetString(col++)); }
                    if (columns.Predicate) { p = SelectEntity(reader.GetInt32(col++), reader.GetString(col++)); }
                    if (columns.Object) { o = SelectResource(reader.GetInt32(col++), reader.GetString(col++), reader.GetString(col++), reader.GetString(col++)); }
                    if (columns.Meta) { m = SelectEntity(reader.GetInt32(col++), reader.GetString(col++)); }

                    if (filter.LiteralFilters != null && !LiteralFilter.MatchesFilters(o, filter.LiteralFilters, this))
                        continue;

                    bool ret = result.Add(new Statement(s, p, o, m));
                    if (!ret) break;
                }
            }
        }