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; }
//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; }
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; }
//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); }