public RequestExecutionContextCacheInfo(long hashCode)
        {
            if (hashCode == 0)
            {
                throw new ArgumentOutOfRangeException("hashCode", hashCode, "hashCode must be non-zero");
            }

            HashCode = hashCode;
            ParsedRequest = new ParsedRequest(true);
            RequestParams = new DataRequestParams();
            RequestBulk = new DataRequestBulk();
        }
        private void ParseRequest(DataRequest request, DataRequestBulk requestBulk, ParsedRequest parsedRequest, CancellationToken cancellation)
        {
            if (parsedRequest.SpecialCommand.IsSpecialCommand)
            {
                if (parsedRequest.SpecialCommand.CommandType != ParsedRequest.SpecialCommandData.SpecialCommandType.Defragment)
                {
                    throw new CompilationException(
                        "Invalid special command type: " + parsedRequest.SpecialCommand.CommandType + ". Command text was: " + request.CommandText);
                }

                return;
            }

            // by now, we have all information about the request at hand, including parameter values data.
            // parser will write results into cacheInfo object
            m_parser.Parse(request, requestBulk, parsedRequest, cancellation);

            if (parsedRequest.StatementType == StatementType.Delete || parsedRequest.StatementType == StatementType.Insert)
            {
                // for insert and delete, we need all columns' data ready for modification before we start
                m_storageDriver.PrepareAllColumnsAndWait(parsedRequest.TargetEntity.DocumentType);
            }
            else
            {
                // for other statement types, we only need fields that we order by, filter on, fetch or update,
                // and we need them in that particular order.

                // schedule loading of sort order fields
                foreach (var field in parsedRequest.BaseDataset.OrderClauseFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.Item1);
                }

                // schedule loading of where clause fields
                foreach (var field in parsedRequest.BaseDataset.WhereClauseFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }

                // schedule loading of fetched fields
                foreach (var field in parsedRequest.Select.SelectFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }

                // schedule loading of inserted/updated fields
                foreach (var field in parsedRequest.Modify.ModifiedFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }
            }
        }
        /// <summary>
        /// Computes an Int64 hash value for a request for use with dictionary of prepared requests.
        /// </summary>
        public static long GetRequestHash(DataRequest request, DataRequestBulk requestBulk, DataRequestParams requestParams)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (request.HaveRequestBulk && requestBulk == null)
            {
                throw new ArgumentNullException("requestBulk");
            }

            if (request.HaveParameters && requestParams == null)
            {
                throw new ArgumentNullException("requestParams");
            }

            long hash;
            int modulo;
            InitHash(out hash, out modulo);

            if (request.HaveRequestBulk)
            {
                AppendToHash(ref hash, modulo, (requestBulk.EntityName ?? string.Empty).GetHashCode());
                AppendToHash(ref hash, modulo, (int)requestBulk.DbStatementType);

                foreach (var f in requestBulk.FieldNames)
                {
                    AppendToHash(ref hash, modulo, f.GetHashCode());
                }
            }
            else
            {
                AppendToHash(ref hash, modulo, (request.CommandText ?? string.Empty).GetHashCode());

                if (request.HaveParameters)
                {
                    foreach (var dataType in requestParams.DataTypes)
                    {
                        AppendToHash(ref hash, modulo, (int)dataType);
                    }

                    foreach (var bitVectorData in requestParams.IsCollectionFlags)
                    {
                        AppendToHash(ref hash, modulo, bitVectorData);
                    }
                }
            }

            return hash;
        }
        /// <summary>
        /// Reads portion of request headers appropriate for caching into the cache buffer.
        /// </summary>
        public void ReadRequestHeaders(DataRequest request, DataRequestParams requestParams, DataRequestBulk requestBulk, ParsedRequest parsedRequest)
        {
            if (request == null)
            {
                throw new ArgumentNullException("requestParams");
            }

            CommandText = request.CommandText;

            RequestParams.Clear();
            RequestBulk.Clear();

            if (request.HaveParameters)
            {
                RequestParams.DataTypes = requestParams.DataTypes;
                RequestParams.IsCollectionFlags = requestParams.IsCollectionFlags;
                RequestParams.Names = requestParams.Names;

                // some values are written into parsed request during request read process
                // have to replicate them in the cached version, because they are required for subsequent compilation
                ParsedRequest.Params.Names = parsedRequest.Params.Names;
                ParsedRequest.Params.DataTypes = parsedRequest.Params.DataTypes;
                ParsedRequest.Params.OrdinalToLocalOrdinal = parsedRequest.Params.OrdinalToLocalOrdinal;
            }

            if (request.HaveRequestBulk)
            {
                RequestBulk.DbStatementType = requestBulk.DbStatementType;
                RequestBulk.EntityName = requestBulk.EntityName;
                RequestBulk.FieldNames = requestBulk.FieldNames;

                // some values are written into parsed request during request read process
                // have to replicate them in the cached version, because they are required for subsequent compilation
                ParsedRequest.IsBulk = parsedRequest.IsBulk;
            }

            if (StringComparer.OrdinalIgnoreCase.Equals(CommandText, "defragment"))
            {
                ParsedRequest.SpecialCommand.IsSpecialCommand = true;
                ParsedRequest.SpecialCommand.CommandType = ParsedRequest.SpecialCommandData.SpecialCommandType.Defragment;
            }

            HaveRequestHeaders = true;
        }
Esempio n. 5
0
        private PqlMessage SendCommand(IDataService channel, DataRequest dataRequest, DataRequestParams dataRequestParams, DataRequestBulk dataRequestBulk)
        {
            var authContext = m_connection.ClientSecurityContext;

            if (authContext == null)
            {
                throw new InvalidOperationException("Authentication context is not set on the thread");
            }

            if (string.IsNullOrWhiteSpace(authContext.TenantId))
            {
                throw new InvalidOperationException("Current authentication context does not have value for TenantId");
            }

            Message responseMessage;
            using (var holder = PqlDataConnection.CommandStreams.Take(m_connection.CancellationTokenSource.Token))
            {
                holder.Item.Attach(dataRequest, dataRequestParams, dataRequestBulk);

                var requestMessage = new PqlMessage(
                    holder.Item, new IDisposable[] {holder},
                    AuthContextSerializer.GetString(authContext),
                    m_connection.ConnectionProps.ScopeId,
                    m_connection.ConnectionProps.ProtocolVersion);

                responseMessage = channel.Process(requestMessage);
            }

            var pqlMessage = responseMessage as PqlMessage;

            if (pqlMessage != null)
            {
                return pqlMessage;
            }

            throw new DataException(string.Format(
                "Message must be of type {0}. Actual type that came from WCF transport was {1}",
                typeof(PqlMessage).AssemblyQualifiedName,
                responseMessage.GetType().AssemblyQualifiedName));
        }
Esempio n. 6
0
        private void ParseBulkRequest(DataRequestBulk requestBulk, ParsedRequest parsedRequest)
        {
            switch (requestBulk.DbStatementType)
            {
                case StatementType.Insert:
                case StatementType.Update:
                    parsedRequest.StatementType = requestBulk.DbStatementType;
                    break;

                default:
                    throw new ArgumentOutOfRangeException("requestBulk", requestBulk.DbStatementType, "Invalid bulk statement type");
            }

            parsedRequest.TargetEntity = m_containerDescriptor.RequireDocumentType(
                m_containerDescriptor.RequireDocumentTypeName(requestBulk.EntityName));

            if (string.IsNullOrEmpty(parsedRequest.TargetEntity.PrimaryKeyFieldName))
            {
                throw new Exception("Target entity does not have a primary key, cannot perform bulk operations on it");
            }

            parsedRequest.TargetEntityPkField = m_containerDescriptor.RequireField(
                parsedRequest.TargetEntity.DocumentType, parsedRequest.TargetEntity.PrimaryKeyFieldName);

            // we always expect value of primary key into driver row data for bulk requests at first position
            parsedRequest.OrdinalOfPrimaryKey = 0;

            if (0 != StringComparer.OrdinalIgnoreCase.Compare(requestBulk.FieldNames[0], parsedRequest.TargetEntityPkField.Name))
            {
                throw new Exception("First field in bulk request input schema on this entity must be the primary key field");
            }

            for (var ordinal = 0; ordinal < requestBulk.FieldNames.Length; ordinal++)
            {
                var fieldName = requestBulk.FieldNames[ordinal];
                var field = m_containerDescriptor.RequireField(parsedRequest.TargetEntity.DocumentType, fieldName);

                if (ordinal != 0 && ReferenceEquals(parsedRequest.TargetEntityPkField, field))
                {
                    throw new Exception("Primary key field may only be used in first position");
                }

                if (parsedRequest.Modify.ModifiedFields.Contains(field))
                {
                    throw new CompilationException("A field can be assigned only once: " + field.Name, null);
                }

                parsedRequest.BulkInput.BulkInputFields.Add(field);
                parsedRequest.Modify.ModifiedFields.Add(field);
                parsedRequest.Modify.InsertUpdateSetClauses.Add(null);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Parses specified expression text, with a cancellation option. 
        /// May incur some waiting in highly concurrent environment, because the number of pooled parsers is limited.
        /// </summary>
        public void Parse(DataRequest request, DataRequestBulk requestBulk, ParsedRequest parsedRequest, CancellationToken cancellation)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (parsedRequest == null)
            {
                throw new ArgumentNullException("parsedRequest");
            }

            if (cancellation == null)
            {
                throw new ArgumentNullException("cancellation");
            }

            if (request.HaveRequestBulk && requestBulk == null)
            {
                throw new ArgumentNullException("requestBulk");
            }

            if (request.HaveRequestBulk)
            {
                ParseBulkRequest(requestBulk, parsedRequest);
            }
            else
            {
                ParsePqlStatementRequest(request, parsedRequest, cancellation);
            }

            InitDriverFetchFields(parsedRequest);
        }
        /// <summary>
        /// Ctr.
        /// </summary>
        /// <param name="process">Parent process, receives crash notifications</param>
        /// <param name="tracer">Tracer object</param>
        public RequestExecutionContext(IPqlEngineHostProcess process, ITracer tracer)
        {
            if (process == null)
            {
                throw new ArgumentNullException("process");
            }

            if (tracer == null)
            {
                throw new ArgumentNullException("tracer");
            }

            m_tracer = tracer;

            m_process = process;

            ParsedRequest = new ParsedRequest(false);
            Request = new DataRequest();
            RequestBulk = new DataRequestBulk();
            RequestParameters = new DataRequestParams();

            m_buffersRingItems = new []
                {
                    new RequestExecutionBuffer(),
                    new RequestExecutionBuffer(),
                    new RequestExecutionBuffer()
                };
        }