예제 #1
0
        private void checkForError(IErlObject pattern, IErlObject response, ErlVarBind bind, int reqID)
        {
            if (bind != null)
            {
                return;
            }

            bind = response.Match(pattern);
            if (bind == null)
            {
                throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESP_PROTOCOL_ERROR + "invalid error response pattern", new Exception(response.ToString()));
            }

            var gotReqID = bind[ATOM_ReqID].ValueAsLong;

            if (gotReqID != reqID)
            {
                throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESP_PROTOCOL_ERROR + "unexpected transaction ID (expected={0}, got={1})".Args(reqID, gotReqID));
            }

            var ecode = bind[ATOM_Code].ValueAsInt;
            var rmsg  = bind[ATOM_Msg];
            var emsg  = rmsg.TypeOrder == ErlTypeOrder.ErlString || rmsg.TypeOrder == ErlTypeOrder.ErlAtom
                  ? rmsg.ValueAsString
                  : rmsg.ToString();

            Exception error;

            switch (ecode)
            {
            case INVALID_SUBSCRIPTION_REQUEST_EXCEPTION:
                error = new NFX.DataAccess.CRUD.Subscriptions.InvalidSubscriptionRequestException(emsg, null);
                break;

            case -1:
                error = new ErlDataAccessException("Remote error message: {0}".Args(emsg));
                break;

            default:
                error = new ErlDataAccessException("Remote error code {0}. Message: {1}".Args(ecode, emsg));
                break;
            }

            throw error;
        }
예제 #2
0
      //used for subscription
      public int ExecuteWithoutFetch(ICRUDQueryExecutionContext context, Query query)
      {
        var store = ((ErlCRUDQueryExecutionContext)context).DataStore;
        var mbox = ((ErlCRUDQueryExecutionContext)context).ErlMailBox;
        var ts = ((ErlCRUDQueryExecutionContext)context).SubscriptionTimestamp;

        if (!ts.HasValue)
          throw new ErlDataAccessException(StringConsts.ERL_DS_QUERY_TIMESTAMP_CTX_ABSENT_ERROR);

        var parsed = prepareQuery(m_Source);

        var reqID = m_Store.NextRequestID;
        
        var bind = new ErlVarBind();

        var wass = false;
        var wast = false;
        foreach(var erlVar in parsed.ArgVars)
        {
           var name = erlVar.Name.Value;

           if (erlVar.Name==ATOM_Subscriber && 
               erlVar.ValueType==ErlTypeOrder.ErlPid)
           {
             bind.Add(ATOM_Subscriber, mbox.Self);
             wass = true;
             continue;
           }

           if (erlVar.Name==ATOM_Timestamp && 
               erlVar.ValueType==ErlTypeOrder.ErlLong)
           {
             bind.Add(ATOM_Timestamp, new ErlLong(ts.Value.Microseconds));
             wast = true;
             continue;
           }

           var clrPar = query[name];
           if (clrPar==null)
            throw new ErlDataAccessException(StringConsts.ERL_DS_QUERY_PARAM_NOT_FOUND_ERROR.Args(parsed.Source, name));

           bind.Add(erlVar, clrPar.Value);
        }

        if (!wass)
          throw new ErlDataAccessException(StringConsts.ERL_DS_QUERY_SUBSCRIBER_NOT_FOUND_ERROR);
        if (!wast)
          throw new ErlDataAccessException(StringConsts.ERL_DS_QUERY_TIMESTAMP_NOT_FOUND_ERROR);


        var request = parsed.ArgTerm.Subst(bind);

        var args = new ErlList
        {
          reqID.ToErlObject(),
          parsed.Module,
          parsed.Function,
          request
        };

        var rawResp = store.ExecuteRPC(ErlDataStore.NFX_CRUD_MOD, 
                                       ErlDataStore.NFX_SUBSCRIBE_FUN, args, null);
                                        
        var response = rawResp as ErlTuple; 

        // {ReqID, {ok, SchemaID, [{row},{row}...]}}
        // {ReqID, {ReqID::int(), {error, Code::int(), Msg}}}

        if (response==null)
          throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESPONSE_PROTOCOL_ERROR+"QryHndlr.Response==null");


        bind = response.Match(EXECUTE_SUBSCRIBE_OK_PATTERN);
        if (bind==null)
        {
          bind = response.Match(EXECUTE_SUBSCRIBE_ERROR_PATTERN);
          if (bind==null || bind[ATOM_ReqID].ValueAsLong != reqID)
            throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESPONSE_PROTOCOL_ERROR+"QryHndlr.Response wrong error");

          var ecode = bind[ATOM_Code].ValueAsInt;
          var emsg  = bind[ATOM_Msg].ToString();

          Exception error = new ErlDataAccessException("Remote error code {0}. Message: '{1}'".Args(ecode, emsg));

          if (ecode==INVALID_SUBSCRIPTION_REQUEST_EXCEPTION)
           error = new NFX.DataAccess.CRUD.Subscriptions.InvalidSubscriptionRequestException(emsg, error);

          throw error;
        }

        if (bind[ATOM_ReqID].ValueAsLong != reqID)
            throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESPONSE_PROTOCOL_ERROR+"QryHndlr.Response.ReqID mismatch");

        //{ReqID::int(), ok}
        return 0;
      }
예제 #3
0
        private void checkForError(IErlObject pattern, IErlObject response, ErlVarBind bind, int reqID)
        {
            if (bind != null)
              return;

            bind = response.Match(pattern);
            if (bind == null)
              throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESP_PROTOCOL_ERROR + "invalid error response pattern", new Exception(response.ToString()));

            var gotReqID = bind[ATOM_ReqID].ValueAsLong;

            if (gotReqID != reqID)
              throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESP_PROTOCOL_ERROR + "unexpected transaction ID (expected={0}, got={1})".Args(reqID, gotReqID));

            var ecode = bind[ATOM_Code].ValueAsInt;
            var rmsg  = bind[ATOM_Msg];
            var emsg  = rmsg.TypeOrder == ErlTypeOrder.ErlString || rmsg.TypeOrder == ErlTypeOrder.ErlAtom
                  ? rmsg.ValueAsString
                  : rmsg.ToString();

            Exception error;

            switch (ecode)
            {
              case INVALID_SUBSCRIPTION_REQUEST_EXCEPTION:
            error = new NFX.DataAccess.CRUD.Subscriptions.InvalidSubscriptionRequestException(emsg, null);
            break;
              case -1:
            error = new ErlDataAccessException("Remote error message: {0}".Args(emsg));
            break;
              default:
            error = new ErlDataAccessException("Remote error code {0}. Message: {1}".Args(ecode, emsg));
            break;
            }

            throw error;
        }
예제 #4
0
        //used for subscription
        public int ExecuteWithoutFetch(ICRUDQueryExecutionContext context, Query query)
        {
            var store = ((ErlCRUDQueryExecutionContext)context).DataStore;
            var mbox  = ((ErlCRUDQueryExecutionContext)context).ErlMailBox;
            var ts    = ((ErlCRUDQueryExecutionContext)context).SubscriptionTimestamp;

            if (!ts.HasValue)
            {
                throw new ErlDataAccessException(StringConsts.ERL_DS_QUERY_TIMESTAMP_CTX_ABSENT_ERROR);
            }

            var parsed = prepareQuery(m_Source);

            var reqID = m_Store.NextRequestID;

            var bind = new ErlVarBind();

            var wass = false;
            var wast = false;

            foreach (var erlVar in parsed.ArgVars)
            {
                var name = erlVar.Name.Value;

                if (erlVar.Name == ATOM_Subscriber &&
                    erlVar.ValueType == ErlTypeOrder.ErlPid)
                {
                    bind.Add(ATOM_Subscriber, mbox.Self);
                    wass = true;
                    continue;
                }

                if (erlVar.Name == ATOM_Timestamp &&
                    erlVar.ValueType == ErlTypeOrder.ErlLong)
                {
                    bind.Add(ATOM_Timestamp, new ErlLong(ts.Value.Microseconds));
                    wast = true;
                    continue;
                }

                var clrPar = query[name];
                if (clrPar == null)
                {
                    throw new ErlDataAccessException(StringConsts.ERL_DS_QUERY_PARAM_NOT_FOUND_ERROR.Args(parsed.Source, name));
                }

                bind.Add(erlVar, clrPar.Value);
            }

            if (!wass)
            {
                throw new ErlDataAccessException(StringConsts.ERL_DS_QUERY_SUBSCRIBER_NOT_FOUND_ERROR);
            }
            if (!wast)
            {
                throw new ErlDataAccessException(StringConsts.ERL_DS_QUERY_TIMESTAMP_NOT_FOUND_ERROR);
            }


            var request = parsed.ArgTerm.Subst(bind);

            var args = new ErlList
            {
                reqID.ToErlObject(),
                parsed.Module,
                parsed.Function,
                request
            };

            var rawResp = store.ExecuteRPC(ErlDataStore.NFX_CRUD_MOD,
                                           ErlDataStore.NFX_SUBSCRIBE_FUN, args, null);

            var response = rawResp as ErlTuple;

            // {ReqID, {ok, SchemaID, [{row},{row}...]}}
            // {ReqID, {ReqID::int(), {error, Code::int(), Msg}}}

            if (response == null)
            {
                throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESPONSE_PROTOCOL_ERROR + "QryHndlr.Response==null");
            }


            bind = response.Match(EXECUTE_SUBSCRIBE_OK_PATTERN);
            if (bind == null)
            {
                bind = response.Match(EXECUTE_SUBSCRIBE_ERROR_PATTERN);
                if (bind == null || bind[ATOM_ReqID].ValueAsLong != reqID)
                {
                    throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESPONSE_PROTOCOL_ERROR + "QryHndlr.Response wrong error");
                }

                var ecode = bind[ATOM_Code].ValueAsInt;
                var emsg  = bind[ATOM_Msg].ToString();

                Exception error = new ErlDataAccessException("Remote error code {0}. Message: '{1}'".Args(ecode, emsg));

                if (ecode == INVALID_SUBSCRIPTION_REQUEST_EXCEPTION)
                {
                    error = new NFX.DataAccess.CRUD.Subscriptions.InvalidSubscriptionRequestException(emsg, error);
                }

                throw error;
            }

            if (bind[ATOM_ReqID].ValueAsLong != reqID)
            {
                throw new ErlDataAccessException(StringConsts.ERL_DS_INVALID_RESPONSE_PROTOCOL_ERROR + "QryHndlr.Response.ReqID mismatch");
            }

            //{ReqID::int(), ok}
            return(0);
        }