private static DateTime erlDate2DateTime(IErlObject erl) { try { var date = (ErlTuple)erl; var y = date[0].ValueAsInt; var m = date[1].ValueAsInt; var d = date[2].ValueAsInt; return(new DateTime(y, m, d, 0, 0, 0, DateTimeKind.Utc)); } catch (Exception e) { throw new ErlException(StringConsts.ERL_INVALID_VALUE_ERROR.Args(erl.ToString()), e); } }
internal static object ErlToClrValue(IErlObject erlValue, Schema schema, Schema.FieldDef fdef, string targetName = null, IErlObject outerTerm = null) { if (erlValue.IsNull()) { return(null); } var atr = fdef[targetName]; var dataType = atr.BackendType; if (dataType.IsNullOrWhiteSpace()) { throw new ErlDataAccessException(StringConsts.ERL_DS_INTERNAL_MAPPING_ERROR + "fielddef '{0}.{1}' has no backend type".Args(schema.Name, fdef.Name)); } Tuple <Type, Func <IErlObject, object> > mapping; if (ERL_TO_CLR_TYPEMAP.TryGetValue(dataType, out mapping)) { try { return(mapping.Item2(erlValue)); } catch (Exception error) { var err = "Schema '{0}' field '{1}' ({2}) cannot be converted from '{3}' to '{4}' format{5}" .Args(schema.Name, fdef.Name, erlValue.ToString(), erlValue.GetType(), dataType, outerTerm == null ? "" : " in record:\n {0}".Args(outerTerm.ToString())); App.Log.Write(new Log.Message { Type = Log.MessageType.TraceErl, Topic = CoreConsts.ERLANG_TOPIC, From = "SchemaMap.ErlTupleToRow({0})".Args(schema.Name), Text = err + error.ToMessageWithType(), Exception = error }); throw new ErlDataAccessException(err, inner: error); } } var er = StringConsts.ERL_DS_INTERNAL_MAPPING_ERROR + "erltype'{0}' not matched in the dict".Args(dataType); throw new ErlDataAccessException(er); }
/// <summary> /// Tries to convert an Erlang term as specified native type. /// Throw exception if conversion is not possible /// </summary> public static object AsType(this IErlObject val, Type t) { try { if (typeof(IErlObject).IsAssignableFrom(t)) { return(val); } if (t == typeof(string)) { return(val.ValueAsString); } if (t == typeof(int)) { return(val.ValueAsInt); } if (t == typeof(long)) { return(val.ValueAsLong); } if (t == typeof(short)) { return((short)val.ValueAsInt); } if (t == typeof(bool)) { return(val.ValueAsBool); } if (t == typeof(float)) { return((float)val.ValueAsDouble); } if (t == typeof(double)) { return(val.ValueAsDouble); } if (t == typeof(decimal)) { return(val.ValueAsDecimal); } if (t == typeof(TimeSpan)) { return(val.ValueAsTimeSpan); } if (t == typeof(DateTime)) { return(val.ValueAsDateTime); } if (t == typeof(object)) { return(val); } if (t.IsEnum) { return(Enum.Parse(t, val.ValueAsString, true)); } bool empty = string.IsNullOrEmpty(val.ValueAsString); if (t == typeof(int?)) { return(empty ? (int?)null : val.ValueAsInt); } if (t == typeof(long?)) { return(empty ? (long?)null : val.ValueAsLong); } if (t == typeof(short?)) { return(empty ? (short?)null : (short)val.ValueAsInt); } if (t == typeof(bool?)) { return(empty ? (bool?)null : val.ValueAsBool); } if (t == typeof(float?)) { return(empty ? (float?)null : (float)val.ValueAsDouble); } if (t == typeof(double?)) { return(empty ? (double?)null : val.ValueAsDouble); } if (t == typeof(decimal?)) { return(empty ? (decimal?)null : val.ValueAsDecimal); } if (t == typeof(TimeSpan?)) { return(empty ? (TimeSpan?)null : val.ValueAsTimeSpan); } if (t == typeof(DateTime?)) { return(empty ? (DateTime?)null : val.ValueAsDateTime); } if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { var v = val.ToString(); if (string.IsNullOrWhiteSpace(v)) { return(null); } var gargs = t.GetGenericArguments(); if (gargs.Length == 1) { var gtp = gargs[0]; if (gtp.IsEnum) { return(Enum.Parse(gtp, v, true)); } } } } catch (Exception e) { throw new NFXException(StringConsts.ERL_CANNOT_CONVERT_TYPES_ERROR.Args(val.GetType().Name, t.FullName), e); } throw new ErlException(StringConsts.ERL_CANNOT_CONVERT_TYPES_ERROR, val.GetType().Name, t.FullName); }
public void ErlTupleTest() { var l = new ErlTuple("test", 1, 1.1, true, (byte)255, 'x', new ErlAtom("a")); var r = new ErlTuple("test", 1, 1.1, true, (byte)255, 'x', new ErlAtom("a")); Assert.AreEqual(7, l.Count); Assert.AreEqual(ErlTypeOrder.ErlString, l[0].TypeOrder); Assert.AreEqual("test", l[0].ValueAsString); Assert.AreEqual(ErlTypeOrder.ErlLong, l[1].TypeOrder); Assert.AreEqual(1, l[1].ValueAsInt); Assert.AreEqual(ErlTypeOrder.ErlDouble, l[2].TypeOrder); Assert.AreEqual(1.1, l[2].ValueAsDouble); Assert.AreEqual(ErlTypeOrder.ErlBoolean, l[3].TypeOrder); Assert.AreEqual(true, l[3].ValueAsBool); Assert.AreEqual(ErlTypeOrder.ErlByte, l[4].TypeOrder); Assert.AreEqual(255, l[4].ValueAsInt); Assert.AreEqual(ErlTypeOrder.ErlByte, l[5].TypeOrder); Assert.AreEqual('x', l[5].ValueAsChar); Assert.AreEqual(ErlTypeOrder.ErlAtom, l[6].TypeOrder); Assert.AreEqual("a", l[6].ValueAsString); Assert.IsTrue(l.Matches(r)); Assert.AreEqual(new ErlVarBind(), l.Match(r)); Assert.AreEqual(l, r); Assert.IsTrue(l.Equals(r)); Assert.AreEqual("{\"test\",1,1.1,true,255,120,a}", l.ToString()); Assert.IsFalse(l.IsScalar); Assert.AreEqual(ErlTypeOrder.ErlTuple, l.TypeOrder); IErlObject temp = null; Assert.IsFalse(l.Subst(ref temp, new ErlVarBind())); Assert.AreEqual(1, l.Visit(0, (acc, o) => acc + (o is ErlAtom ? 1 : 0))); Assert.IsTrue(new ErlTuple(new ErlVar(X), true, 1).Subst(ref temp, new ErlVarBind { { X, new ErlLong(10) } })); Assert.AreEqual("{10,true,1}", temp.ToString()); var d = new DateTime(2013, 1, 2); var ts = new TimeSpan(1, 2, 3); Assert.DoesNotThrow(() => { var x = l.ValueAsObject; }); Assert.AreEqual(1, new ErlList("1")[0].ValueAsInt); Assert.AreEqual(1, new ErlList("1")[0].ValueAsLong); Assert.AreEqual(1, new ErlList("1")[0].ValueAsDecimal); Assert.AreEqual(d, new ErlList(d.ToString())[0].ValueAsDateTime); Assert.AreEqual(ts, new ErlList(ts.ToString())[0].ValueAsTimeSpan); Assert.AreEqual(1.0, new ErlList("1.0")[0].ValueAsDouble); Assert.AreEqual("a", new ErlList("a")[0].ValueAsString); Assert.IsTrue(new ErlList("true")[0].ValueAsBool); Assert.IsFalse(new ErlList("xxxx")[0].ValueAsBool); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsInt; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsLong; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsDecimal; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsDateTime; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsTimeSpan; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsDouble; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsString; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsBool; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsChar; }); Assert.Throws <ErlIncompatibleTypesException>(() => { var x = l.ValueAsByteArray; }); List <IErlObject> s = l; Assert.AreEqual(l.Value, s); Assert.IsFalse(new ErlList(1, 1.0, "a").Equals(new ErlTuple(1, 1.0, "a"))); Assert.IsFalse(new ErlList(1, 1.0, "a") == new ErlTuple(1, 1.0, "a")); Assert.IsTrue(new ErlList(1, 1.0, "a") == new ErlList(1, 1.0, "a")); }
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; }
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; }
private static DateTime erlDate2DateTime(IErlObject erl) { try { var date = (ErlTuple)erl; var y = date[0].ValueAsInt; var m = date[1].ValueAsInt; var d = date[2].ValueAsInt; return new DateTime(y, m, d, 0, 0, 0, DateTimeKind.Utc); } catch (Exception e) { throw new ErlException(StringConsts.ERL_INVALID_VALUE_ERROR.Args(erl.ToString()), e); } }
private static string erlIP2String(IErlObject erl) { try { return string.Join(".", ((ErlTuple) erl).Value.Select(i => i.ValueAsInt.ToString()).Take(4)); } catch (Exception e) { throw new ErlException(StringConsts.ERL_INVALID_VALUE_ERROR.Args(erl.ToString()), e); } }
internal static object ErlToClrValue(IErlObject erlValue, Schema schema, Schema.FieldDef fdef, string targetName = null, IErlObject outerTerm = null) { if (erlValue.IsNull()) return null; var atr = fdef[targetName]; var dataType = atr.BackendType; if (dataType.IsNullOrWhiteSpace()) throw new ErlDataAccessException(StringConsts.ERL_DS_INTERNAL_MAPPING_ERROR + "fielddef '{0}.{1}' has no backend type".Args(schema.Name, fdef.Name)); Tuple<Type, Func<IErlObject, object>> mapping; if (ERL_TO_CLR_TYPEMAP.TryGetValue(dataType, out mapping)) { try { return mapping.Item2(erlValue); } catch (Exception error) { var err = "Schema '{0}' field '{1}' ({2}) cannot be converted from '{3}' to '{4}' format{5}" .Args(schema.Name, fdef.Name, erlValue.ToString(), erlValue.GetType(), dataType, outerTerm == null ? "" : " in record:\n {0}".Args(outerTerm.ToString())); App.Log.Write(new Log.Message { Type = Log.MessageType.TraceErl, Topic = CoreConsts.ERLANG_TOPIC, From = "SchemaMap.ErlTupleToRow({0})".Args(schema.Name), Text = err + error.ToMessageWithType(), Exception = error }); throw new ErlDataAccessException(err, inner: error); } } var er = StringConsts.ERL_DS_INTERNAL_MAPPING_ERROR + "erltype'{0}' not matched in the dict".Args(dataType); throw new ErlDataAccessException(er); }