예제 #1
0
        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));
        }
예제 #2
0
        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));
        }
예제 #3
0
        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);
        }