예제 #1
0
        public override object LoadScalar(OPath.OPathQuery query)
        {
            if (query.QueryType == OPathQueryTypeEnum.Path)
            {
                query.QueryType = OPathQueryTypeEnum.Expression;
                query.Expression = new OPath.Expressions.Call("eval", new Evaluant.OPath.Expressions.Collections.ConstraintCollection(new OPath.Expressions.Constraint[] { query.Path }));
            }

            SqlMapperTransformer transformer = new SqlMapperTransformer(_Mapping, _Model);
            transformer.Dialect = Dialect;

            ISQLExpression exp = transformer.TransformScalar(query);

            _Connection.Open();
            _Transaction = _Connection.BeginTransaction();

            object result = null;
            try
            {
                string[] queries = Dialect.RenderQueries(exp);

                IDbCommand command = Driver.CreateCommand(queries[queries.Length - 1], _Connection, _Transaction);

                if (TraceSqlSwitch.Enabled)
                {
                    TraceHelpler.Trace(command, _Dialect);
                }

                object res = command.ExecuteScalar();
                if (res != DBNull.Value)
                    result = res;

                _Transaction.Commit();
            }
            catch
            {
                _Transaction.Rollback();
                throw;
            }
            finally
            {
                _Connection.Close();
            }

            // Ensure the result in an Int32 in case of a count()
            if (query.Expression.Operands[0] is OPath.Expressions.Function
                && ((OPath.Expressions.Function)query.Expression.Operands[0]).Type == Evaluant.OPath.Expressions.FunctionEnum.Count)
                result = Convert.ToInt32(result);

            return result;
        }
예제 #2
0
        public override void LoadReference(IEnumerable entities, string[] references)
        {
            //	references = null => don't load references
            if (references == null)
                return;

            //	Group entities by type
            Hashtable orderedEntities = new Hashtable();
            foreach (Entity e in entities)
            {
                if (!orderedEntities.ContainsKey(e.Type))
                    orderedEntities.Add(e.Type, new EntitySet());

                ((EntitySet)orderedEntities[e.Type]).Add(e);

                e.RemoveReference(references);
            }

            //	Process each entity by type
            foreach (string entityType in orderedEntities.Keys)
            {
                Hashtable entityIndex = new Hashtable();
                foreach (Entity entity in ((EntitySet)orderedEntities[entityType]))
                    entityIndex.Add(entity.Id, entity);

                string[] ids = new string[((EntitySet)orderedEntities[entityType]).Count];
                int i = 0;
                foreach (Entity e in (EntitySet)orderedEntities[entityType])
                    ids[i++] = e.Id;

                string id = String.Join("', '", ids);

                Hashtable refs = GetReferenceMappings(entityType, references);

                //	Process each reference of the current entity type
                foreach (string refName in refs.Keys)
                {
                    ReferenceMapping rm = (ReferenceMapping)refs[refName];
                    Evaluant.Uss.Models.Reference referenceModel =
                        _Model.GetReference(rm.EntityParent.Type, refName.Substring(refName.LastIndexOf('.') + 1), true);

                    if (_Mapping.Entities[referenceModel.ParentType] == null)
                        referenceModel = new Evaluant.Uss.Models.Reference(referenceModel.Name, entityType, referenceModel.ChildType, referenceModel.IsComposition, referenceModel.FromMany, referenceModel.ToMany);

                    string parentType = entityType;

                    string opath = String.Concat(parentType, "[ id( '", id, "' ) ].", refName);
                    OPathQuery opathQuery = new OPathQuery(opath);
                    opathQuery.Compile();

                    if (opathQuery.HasErrors)
                        throw new OPathException(opathQuery);

                    SqlMapperTransformer transformer = new SqlMapperTransformer(_Mapping, _Model);

                    transformer.Dialect = _Dialect;

                    string childType = referenceModel.ChildType;

                    //StringCollection attributes = new StringCollection();
                    //if(_Model.GetEntity(rm.EntityChild) != null)
                    //    attributes = GetInheritedAttributes(rm.EntityChild);

                    //string[] atts = new string[attributes.Count];

                    //for(i = 0; i < attributes.Count; i++)
                    //    atts[i] = attributes[i];
                    string[] atts = new string[0];

                    UnionStatement exp = (UnionStatement)transformer.TransformToSql(opathQuery.Path, atts, new string[] { }, false);

                    //	ToDo : Add expression for children types

                    IList childrenSubTypes = _Model.GetTree(childType);

                    foreach (SelectStatement select in exp.SelectExpressions)
                    {
                        EntityMapping entityChild = _Mapping.Entities[referenceModel.ChildType];

                        //	Insert the ParentId field in case of generic reference mapping
                        //	Then, we can add the OrderBy clause
                        for (int pmkIndex = 0; pmkIndex < rm.EntityParent.Ids.Count; pmkIndex++)
                        {
                            PrimaryKeyMapping pkm = rm.EntityParent.Ids[pmkIndex];
                            string parentIdAlias = SqlMapperTransformer.GetParentIdAlias(rm.EntityParent, pkm.Field);
                            if (!FieldExists(select.SelectList, parentIdAlias))
                                select.SelectList.Insert(2 + pmkIndex, new Column(pkm, select.TableAlias, parentIdAlias, parentIdAlias));

                        }
                    }

                    if (rm.OrderBy != null && rm.OrderBy != string.Empty)
                    {
                        exp.OrderByClause = new OrderByClause(exp);
                        string[] orderbies = rm.OrderBy.Split(',');
                        foreach (string orderby in orderbies)
                        {
                            string[] orderbyDirection = orderby.Split(' ');
                            if (orderbyDirection.Length == 1)
                                exp.OrderByClause.Add(new OrderByClauseColumn(orderbyDirection[0]));
                            else
                                exp.OrderByClause.Add(new OrderByClauseColumn(orderbyDirection[0], orderbyDirection[1].ToLower() == "desc"));
                        }
                    }

                    exp.SelectedAllColumns = true;
                    exp.TableAlias = "q";

                    _Connection.Open();
                    _Transaction = _Connection.BeginTransaction();

                    try
                    {
                        foreach (string q in _Dialect.RenderQueries(exp, Driver))
                        {

                            IDbCommand command = _Driver.CreateCommand(q, _Connection, _Transaction);

                            if (TraceSqlSwitch.Enabled)
                            {
                                TraceHelpler.Trace(command, _Dialect);
                            }

                            using (IDataReader reader = command.ExecuteReader())
                            {

                                EntityMapping entityChild = _Mapping.Entities[referenceModel.ChildType];
                                EntityMapping baseEntityChild = entityChild;
                                string parentId = String.Empty;
                                string refId = null;	//String.Empty;	Empty string can be the value 
                                Entity parentEntity = null, reference = null;

                                while (reader.Read())
                                {
                                    string trueType = reader[SqlMapperTransformer.TYPE_ALIAS].ToString();
                                    if (baseEntityChild == null || baseEntityChild.Type != trueType)
                                        entityChild = _Mapping.Entities[trueType];
                                    if (entityChild == null)
                                        throw new MappingNotFoundException(string.Format("The entity [{0}] could not be found the mapping", trueType));
                                    int nbParentIds = _Mapping.Entities[referenceModel.ParentType].Ids.Count;
                                    string[] newParentIds = new string[nbParentIds];

                                    for (int indexId = 0; indexId < nbParentIds; indexId++)
                                        newParentIds[indexId] = reader.GetValue(reader.GetOrdinal("ParentId" + (nbParentIds == 1 ? "" : indexId.ToString()))).ToString().Trim();

                                    string newParentId = string.Join(SqlMapperProvider.IDSEP.ToString(), newParentIds);

                                    int nbChildIds = entityChild.Ids.Count;
                                    string[] newChildIds = new string[nbChildIds];

                                    for (int indexId = 0; indexId < nbChildIds; indexId++)
                                    {
                                        if (entityChild.Ids[indexId].Generator.Name == Evaluant.Uss.SqlMapper.GeneratorMapping.GeneratorType.business)
                                            newChildIds[indexId] = reader[entityChild.GetIdFieldAs(entityChild.Ids[indexId])].ToString().Trim();
                                        else
                                            newChildIds[indexId] = reader.GetValue(1 + nbParentIds + indexId).ToString().Trim();
                                    }
                                    string newReferenceId = string.Join(SqlMapperProvider.IDSEP.ToString(), newChildIds);

                                    // Go the next parent
                                    if (parentId != newParentId)
                                    {
                                        if (parentEntity != null)
                                            parentEntity.State = State.UpToDate;

                                        parentId = newParentId;
                                        parentEntity = entityIndex[parentId] as Entity;
                                        refId = null;	//String.Empty;	Empty string can be the value 
                                    }

                                    // Create a new reference
                                    if (refId != newReferenceId)
                                    {
                                        if (reference != null)
                                            reference.State = State.UpToDate;

                                        reference = new Entity(entityChild.Type);
                                        refId = newReferenceId;
                                        reference.Id = refId;
                                        parentEntity.AddValue(refName, reference, State.UpToDate);

                                    }
                                    ImportAttributes(reader, new string[] { }, _Mapping.Entities[reference.Type], reference, transformer.ColumnAliasMapping);
                                    entityChild = baseEntityChild;
                                }
                                if (parentEntity != null)
                                    parentEntity.State = State.UpToDate;

                                if (reference != null)
                                    reference.State = State.UpToDate;

                                // mark the reference as loaded for each parentEntity
                                foreach (Entity e in entities)
                                    if (!e.InferredReferences.Contains(refName))
                                        e.InferredReferences.Add(refName);
                            }
                        }

                        _Transaction.Commit();
                    }
                    catch (Exception e)
                    {
                        _Transaction.Rollback();
                        throw e;
                    }
                    finally
                    {
                        _Connection.Close();
                    }
                }
            }
        }
예제 #3
0
        public override EntitySet Load(OPathQuery query, string[] attributes, string orderby, int first, int max)
        {
            if (first <= 0)
                throw new ArgumentException("first must be greater than 0");

            if (max < 0)
                throw new ArgumentException("max must be none negative");

            if (max == 0 && first != 1)
                throw new ArgumentException("max must be greater than zero if a first index is set");

            SqlMapperTransformer transformer = new SqlMapperTransformer(_Mapping, _Model);

            transformer.Dialect = _Dialect;

            ISQLExpression exp = transformer.TransformToSql((Evaluant.OPath.Expressions.Path)query.Path.Clone(),
                attributes,
                orderby == null || orderby == String.Empty ? new string[0] : orderby.Split(','),
                false);

            if (first != 1 || max != 0)
            {
                OPath.Expressions.Function countFunction = new OPath.Expressions.Function(query.Path, Evaluant.OPath.Expressions.FunctionEnum.Count);
                OPath.Expressions.Call callCount = new OPath.Expressions.Call("eval", new Evaluant.OPath.Expressions.Collections.ConstraintCollection(new OPath.Expressions.Constraint[] { countFunction }));
                query.Expression = callCount;
                int maxEntity = Convert.ToInt32(LoadScalar(query));
                if (maxEntity < first)
                    return new EntitySet();		// paging out of range

                if (max == 0)
                    max = maxEntity;

                if (first + max > maxEntity)
                    max = maxEntity - first + 1;

                exp = _Dialect.Page(exp, ((SelectStatement)exp).OrderByClause, first, max);
            }


            return LoadWithSql(exp, transformer.FullNameAttributes, transformer.ColumnAliasMapping, query.Path.Identifiers.Count > 1);
        }