protected DataTable LoadRelationTable(Query query, DataSet ds) { var relations = ObjectContainerStorage.LoadRelations(query.Table.Name, query.Condition); if (!ds.Tables.Contains(query.Table.Name)) { ds.Tables.Add(query.Table.Name); } var tbl = ds.Tables[query.Table.Name]; // ensure columns var fields = query.Fields ?? new[] { (QField)"subject_id", (QField)"object_id" }; foreach (var f in fields) { if (!tbl.Columns.Contains(f.Name)) { tbl.Columns.Add(f.Name, typeof(long)); } } var loadSubj = tbl.Columns.Contains("subject_id"); var loadObj = tbl.Columns.Contains("object_id"); foreach (var rel in relations) { var row = tbl.NewRow(); if (loadSubj) { row["subject_id"] = rel.SubjectID; } if (loadObj) { row["object_id"] = rel.ObjectID; } tbl.Rows.Add(row); } tbl.AcceptChanges(); return(tbl); }
public int Delete(Query query) { var srcName = new QTable(query.Table.Name); var schema = GetSchema(); var dataClass = schema.FindClassByID(query.Table.Name); if (dataClass != null) { var ids = ObjectContainerStorage.GetObjectIds(query); return(ObjectContainerStorage.Delete(ids)); } // check for relation table var relation = schema.FindRelationshipByID(query.Table.Name); if (relation != null) { var rels = ObjectContainerStorage.LoadRelations(query.Table.Name, query.Condition).ToArray(); ObjectContainerStorage.RemoveRelation(rels); return(rels.Length); } return(UnderlyingDalc.Delete(query)); }
protected DataTable LoadObjectTable(Query query, DataSet ds, Class dataClass) { // special count query if (query.Fields != null && query.Fields.Length == 1 && query.Fields[0].Expression != null && query.Fields[0].Expression.ToLower() == "count(*)") { if (ds.Tables.Contains(query.Table.Name)) { ds.Tables.Remove(query.Table.Name); } var t = ds.Tables.Add(query.Table.Name); t.Columns.Add("count", typeof(int)); var cntRow = t.NewRow(); cntRow["count"] = ObjectContainerStorage.GetObjectsCount(query); t.Rows.Add(cntRow); return(t); } DataTable tbl; if (!ds.Tables.Contains(dataClass.ID)) { tbl = ds.Tables.Add(dataClass.ID); } else { tbl = ds.Tables[dataClass.ID]; } // check columns IEnumerable <Property> propsToLoad = null; var relatedPropsToLoad = new Dictionary <Relationship, List <Property> >(); var relationFieldNamePrefix = new Dictionary <Relationship, string>(); var relatedProps = new List <Property>(); if (query.Fields == null) { propsToLoad = dataClass.Properties; } else { var queryProps = new List <Property>(); foreach (var fld in query.Fields) { if (fld.Prefix != null) { var rel = dataClass.Schema.FindRelationshipByID(fld.Prefix); if (rel == null) { rel = dataClass.Schema.InferRelationshipByID(fld.Prefix, dataClass); } if (rel != null) { if (rel.Object == dataClass && !rel.Inferred) { rel = dataClass.FindRelationship(rel.Predicate, rel.Subject, true); } if (rel.Subject != dataClass) { throw new ArgumentException(String.Format( "Relation {0} is not applicable with {1}", fld.Prefix, dataClass.ID)); } var relProp = rel.Object.FindPropertyByID(fld.Name); if (relProp != null) { if (!relatedPropsToLoad.ContainsKey(rel)) { relatedPropsToLoad[rel] = new List <Property>(); } relatedPropsToLoad[rel].Add(relProp); relationFieldNamePrefix[rel] = fld.Prefix.Replace('.', '_'); // for inferred relations relatedProps.Add(relProp); continue; } } } var prop = dataClass.FindPropertyByID(fld.Name); if (prop == null) { throw new Exception(String.Format("Unknown field {0}", fld)); } queryProps.Add(prop); } propsToLoad = queryProps; } // ensure property columns foreach (var p in propsToLoad) { var propType = p.DataType.ValueType; if (p.Multivalue) { propType = propType.MakeArrayType(); } if (!tbl.Columns.Contains(p.ID) || tbl.Columns[p.ID].DataType != propType) { if (tbl.Columns.Contains(p.ID)) { tbl.Columns.Remove(p.ID); } tbl.Columns.Add(p.ID, propType); } } foreach (var relEntry in relatedPropsToLoad) { foreach (var relProp in relEntry.Value) { var propType = relProp.DataType.ValueType; if (relProp.Multivalue || relEntry.Key.Multiplicity) { propType = propType.MakeArrayType(); } var relColName = String.Format("{0}_{1}", relationFieldNamePrefix[relEntry.Key], relProp.ID); if (!tbl.Columns.Contains(relColName) || tbl.Columns[relColName].DataType != propType) { if (tbl.Columns.Contains(relColName)) { tbl.Columns.Remove(relColName); } tbl.Columns.Add(relColName, propType); } } } var ids = ObjectContainerStorage.GetObjectIds(query); var objects = ObjectContainerStorage.Load(ids, propsToLoad.ToArray()); IDictionary <long, ObjectContainer> relatedObjects = null; var objIdToRelationData = new Dictionary <long, List <ObjectRelation> >(); if (relatedPropsToLoad.Count > 0) { var relationData = ObjectContainerStorage.LoadRelations(objects.Values.ToArray(), relatedPropsToLoad.Keys); var relObjIds = new List <long>(); foreach (var r in relationData) { if (!relObjIds.Contains(r.ObjectID)) { relObjIds.Add(r.ObjectID); } if (!objIdToRelationData.ContainsKey(r.SubjectID)) { objIdToRelationData[r.SubjectID] = new List <ObjectRelation>(); } objIdToRelationData[r.SubjectID].Add(r); } relatedObjects = ObjectContainerStorage.Load(relObjIds.ToArray(), relatedProps.ToArray()); } foreach (var id in ids) { if (objects.ContainsKey(id)) { var obj = objects[id]; var r = tbl.NewRow(); foreach (var p in propsToLoad) { r[p.ID] = obj[p] ?? DBNull.Value; } if (relatedPropsToLoad.Count > 0 && objIdToRelationData.ContainsKey(obj.ID.Value)) { foreach (var relEntry in relatedPropsToLoad) { foreach (var rel in objIdToRelationData[obj.ID.Value]) { if (rel.Relation.Equals(relEntry.Key) && relatedObjects.ContainsKey(rel.ObjectID)) { // process related props foreach (var relProp in relEntry.Value) { var relColName = String.Format("{0}_{1}", relationFieldNamePrefix[relEntry.Key], relProp.ID); if (relEntry.Key.Multiplicity) { //TBD: add merge values r[relColName] = r.IsNull(relColName) ? relatedObjects[rel.ObjectID][relProp] : MergeMultivalueColumns(r[relColName], relatedObjects[rel.ObjectID][relProp]); } else { r[relColName] = relatedObjects[rel.ObjectID][relProp]; } } } } } } tbl.Rows.Add(r); r.AcceptChanges(); } } tbl.AcceptChanges(); return(tbl); }