public int Update(Query query, IDictionary <string, IQueryValue> data) { var schema = GetSchema(); var dataClass = schema.FindClassByID(query.Table.Name); if (dataClass != null) { var affectedObjIds = ObjectContainerStorage.GetObjectIds(query); foreach (var objId in affectedObjIds) { var obj = new ObjectContainer(dataClass, objId); foreach (var entry in data) { var valConst = entry.Value as QConst; if (valConst == null) { throw new NotSupportedException( String.Format("Value {0} for {1} is not supported", entry.Value, entry.Key)); } obj[entry.Key] = valConst.Value; } ObjectContainerStorage.Update(obj); } return(affectedObjIds.Length); } var relation = schema.FindRelationshipByID(query.Table.Name); if (relation != null) { throw new NotSupportedException(String.Format("Update is not allowed for relationship {0}", relation.ID)); } return(UnderlyingDalc.Update(query, data)); }
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); }