From 6e4c04b32983f7ee7a0efdbf13463dfaa17966f2 Mon Sep 17 00:00:00 2001 From: karimpour Date: Sun, 14 Jul 2019 13:54:08 +0430 Subject: [PATCH 01/46] add RegExpConstructor --- Signum.React/Scripts/Globals.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Signum.React/Scripts/Globals.ts b/Signum.React/Scripts/Globals.ts index 9f77f2c589..90be4c4dc1 100644 --- a/Signum.React/Scripts/Globals.ts +++ b/Signum.React/Scripts/Globals.ts @@ -3,6 +3,10 @@ declare global { function require(path: string): T; function require(paths: string[], callback: (...modules: any[]) => void): void; + interface RegExpConstructor { + escape(s: string): string; + } + interface Promise { done(this: Promise): void; } From 293efbb89418ce68b33e22b617a596476a67412a Mon Sep 17 00:00:00 2001 From: karimpour Date: Sat, 10 Aug 2019 13:28:37 +0200 Subject: [PATCH 02/46] fixes in Local DateTime --- Signum.Engine/Connection/FieldReader.cs | 1219 +++++++++-------- Signum.React/Scripts/Lines/ValueLine.tsx | 2 +- Signum.React/Scripts/Reflection.ts | 2 +- .../SearchControl/SystemTimeEditor.tsx | 2 +- 4 files changed, 613 insertions(+), 612 deletions(-) diff --git a/Signum.Engine/Connection/FieldReader.cs b/Signum.Engine/Connection/FieldReader.cs index 16e10a199f..09c985d68d 100644 --- a/Signum.Engine/Connection/FieldReader.cs +++ b/Signum.Engine/Connection/FieldReader.cs @@ -1,582 +1,583 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Signum.Utilities.Reflection; -using System.Linq.Expressions; -using System.Reflection; -using Signum.Utilities; -using Signum.Engine.Maps; -using Signum.Entities; -using System.Data.SqlTypes; -using System.Data.Common; -//using Microsoft.SqlServer.Types; -using Signum.Utilities.ExpressionTrees; -using System.Data.SqlClient; -using Microsoft.SqlServer.Server; -using System.IO; - -namespace Signum.Engine -{ - public class FieldReader - { - DbDataReader reader; - TypeCode[] typeCodes; - - private const TypeCode tcGuid = (TypeCode)20; - private const TypeCode tcTimeSpan = (TypeCode)21; - private const TypeCode tcDateTimeOffset = (TypeCode)22; - - public int LastOrdinal; - - TypeCode GetTypeCode(int ordinal) - { - Type type = reader.GetFieldType(ordinal); - TypeCode tc = Type.GetTypeCode(type); - if (tc == TypeCode.Object) - { - if (type == typeof(Guid)) - tc = tcGuid; - - if (type == typeof(TimeSpan)) - tc = tcTimeSpan; - - if (type == typeof(DateTimeOffset)) - tc = tcDateTimeOffset; - } - return tc; - } - - public FieldReader(DbDataReader reader) - { - this.reader = reader; - - this.typeCodes = new TypeCode[reader.FieldCount]; - for (int i = 0; i < typeCodes.Length; i++) - typeCodes[i] = GetTypeCode(i); - } - - public bool IsNull(int ordinal) - { - LastOrdinal = ordinal; - return reader.IsDBNull(ordinal); - } - - public string? GetString(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return reader.GetByte(ordinal).ToString(); - case TypeCode.Int16: - return reader.GetInt16(ordinal).ToString(); - case TypeCode.Int32: - return reader.GetInt32(ordinal).ToString(); - case TypeCode.Int64: - return reader.GetInt64(ordinal).ToString(); - case TypeCode.Double: - return reader.GetDouble(ordinal).ToString(); - case TypeCode.Single: - return reader.GetFloat(ordinal).ToString(); - case TypeCode.Decimal: - return reader.GetDecimal(ordinal).ToString(); - case TypeCode.DateTime: - return reader.GetDateTime(ordinal).ToString(); - case tcGuid: - return reader.GetGuid(ordinal).ToString(); - case TypeCode.String: - return reader.GetString(ordinal); - default: - return reader.GetValue(ordinal).ToString(); - } - } - - public byte[]? GetByteArray(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - - return (byte[])reader.GetValue(ordinal); - } - - public bool GetBoolean(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Boolean: - return reader.GetBoolean(ordinal); - case TypeCode.Byte: - return reader.GetByte(ordinal) != 0; - case TypeCode.Int16: - return reader.GetInt16(ordinal) != 0; - case TypeCode.Int32: - return reader.GetInt32(ordinal) != 0; - case TypeCode.Int64: - return reader.GetInt64(ordinal) != 0; - case TypeCode.String: - return bool.Parse(reader.GetString(ordinal)); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public bool? GetNullableBoolean(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetBoolean(ordinal); - } - - - public Byte GetByte(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return reader.GetByte(ordinal); - case TypeCode.Int16: - return (Byte)reader.GetInt16(ordinal); - case TypeCode.Int32: - return (Byte)reader.GetInt32(ordinal); - case TypeCode.Int64: - return (Byte)reader.GetInt64(ordinal); - case TypeCode.Double: - return (Byte)reader.GetDouble(ordinal); - case TypeCode.Single: - return (Byte)reader.GetFloat(ordinal); - case TypeCode.Decimal: - return (Byte)reader.GetDecimal(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Byte? GetNullableByte(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetByte(ordinal); - } - - - public Char GetChar(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return (Char)reader.GetByte(ordinal); - case TypeCode.Int16: - return (Char)reader.GetInt16(ordinal); - case TypeCode.Int32: - return (Char)reader.GetInt32(ordinal); - case TypeCode.Int64: - return (Char)reader.GetInt64(ordinal); - case TypeCode.Double: - return (Char)reader.GetDouble(ordinal); - case TypeCode.Single: - return (Char)reader.GetFloat(ordinal); - case TypeCode.Decimal: - return (Char)reader.GetDecimal(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Char? GetNullableChar(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetChar(ordinal); - } - - - public Single GetFloat(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return (Single)reader.GetByte(ordinal); - case TypeCode.Int16: - return (Single)reader.GetInt16(ordinal); - case TypeCode.Int32: - return (Single)reader.GetInt32(ordinal); - case TypeCode.Int64: - return (Single)reader.GetInt64(ordinal); - case TypeCode.Double: - return (Single)reader.GetDouble(ordinal); - case TypeCode.Single: - return reader.GetFloat(ordinal); - case TypeCode.Decimal: - return (Single)reader.GetDecimal(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Single? GetNullableFloat(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetFloat(ordinal); - } - - - public Double GetDouble(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return (Double)reader.GetByte(ordinal); - case TypeCode.Int16: - return (Double)reader.GetInt16(ordinal); - case TypeCode.Int32: - return (Double)reader.GetInt32(ordinal); - case TypeCode.Int64: - return (Double)reader.GetInt64(ordinal); - case TypeCode.Double: - return reader.GetDouble(ordinal); - case TypeCode.Single: - return (Double)reader.GetFloat(ordinal); - case TypeCode.Decimal: - return (Double)reader.GetDecimal(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Double? GetNullableDouble(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetDouble(ordinal); - } - - - public Decimal GetDecimal(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return (Decimal)reader.GetByte(ordinal); - case TypeCode.Int16: - return (Decimal)reader.GetInt16(ordinal); - case TypeCode.Int32: - return (Decimal)reader.GetInt32(ordinal); - case TypeCode.Int64: - return (Decimal)reader.GetInt64(ordinal); - case TypeCode.Double: - return (Decimal)reader.GetDouble(ordinal); - case TypeCode.Single: - return (Decimal)reader.GetFloat(ordinal); - case TypeCode.Decimal: - return reader.GetDecimal(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Decimal? GetNullableDecimal(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetDecimal(ordinal); - } - - - public Int16 GetInt16(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return (Int16)reader.GetByte(ordinal); - case TypeCode.Int16: - return reader.GetInt16(ordinal); - case TypeCode.Int32: - return (Int16)reader.GetInt32(ordinal); - case TypeCode.Int64: - return (Int16)reader.GetInt64(ordinal); - case TypeCode.Double: - return (Int16)reader.GetDouble(ordinal); - case TypeCode.Single: - return (Int16)reader.GetFloat(ordinal); - case TypeCode.Decimal: - return (Int16)reader.GetDecimal(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Int16? GetNullableInt16(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetInt16(ordinal); - } - - - public Int32 GetInt32(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return (Int32)reader.GetByte(ordinal); - case TypeCode.Int16: - return (Int32)reader.GetInt16(ordinal); - case TypeCode.Int32: - return reader.GetInt32(ordinal); - case TypeCode.Int64: - return (Int32)reader.GetInt64(ordinal); - case TypeCode.Double: - return (Int32)reader.GetDouble(ordinal); - case TypeCode.Single: - return (Int32)reader.GetFloat(ordinal); - case TypeCode.Decimal: - return (Int32)reader.GetDecimal(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Int32? GetNullableInt32(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetInt32(ordinal); - } - - - public Int64 GetInt64(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case TypeCode.Byte: - return (Int64)reader.GetByte(ordinal); - case TypeCode.Int16: - return (Int64)reader.GetInt16(ordinal); - case TypeCode.Int32: - return (Int64)reader.GetInt32(ordinal); - case TypeCode.Int64: - return (Int64)reader.GetInt64(ordinal); - case TypeCode.Double: - return (Int64)reader.GetDouble(ordinal); - case TypeCode.Single: - return (Int64)reader.GetFloat(ordinal); - case TypeCode.Decimal: - return (Int64)reader.GetDecimal(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Int64? GetNullableInt64(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetInt64(ordinal); - } - - - public DateTime GetDateTime(int ordinal) - { - LastOrdinal = ordinal; - DateTime dt; - switch (typeCodes[ordinal]) - { - case TypeCode.DateTime: - dt = reader.GetDateTime(ordinal); - break; - default: - dt = ReflectionTools.ChangeType(reader.GetValue(ordinal)); - break; - } - - if (Schema.Current.TimeZoneMode == TimeZoneMode.Utc) - return new DateTime(dt.Ticks, DateTimeKind.Utc); - return dt; - } - - public DateTime? GetNullableDateTime(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetDateTime(ordinal); - } - - - public DateTimeOffset GetDateTimeOffset(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case tcDateTimeOffset: - return ((SqlDataReader)reader).GetDateTimeOffset(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public DateTimeOffset? GetNullableDateTimeOffset(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetDateTimeOffset(ordinal); - } - - - public TimeSpan GetTimeSpan(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case tcTimeSpan: - return ((SqlDataReader)reader).GetTimeSpan(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public TimeSpan? GetNullableTimeSpan(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetTimeSpan(ordinal); - } - - - public Guid GetGuid(int ordinal) - { - LastOrdinal = ordinal; - switch (typeCodes[ordinal]) - { - case tcGuid: - return reader.GetGuid(ordinal); - default: - return ReflectionTools.ChangeType(reader.GetValue(ordinal)); - } - } - - public Guid? GetNullableGuid(int ordinal) - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return null; - } - return GetGuid(ordinal); - } - - static MethodInfo miGetUdt = ReflectionTools.GetMethodInfo((FieldReader r) => r.GetUdt(0)).GetGenericMethodDefinition(); - - public T GetUdt(int ordinal) - where T : IBinarySerialize - { - LastOrdinal = ordinal; - if (reader.IsDBNull(ordinal)) - { - return (T)(object)null!; - } - - var udt = Activator.CreateInstance(); - udt.Read(new BinaryReader(reader.GetStream(ordinal))); - return udt; - } - - static Dictionary methods = - typeof(FieldReader).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) - .Where(m => m.Name != "GetExpression" && m.Name != "IsNull") - .ToDictionary(a => a.ReturnType); - - - public static Expression GetExpression(Expression reader, int ordinal, Type type) - { - MethodInfo? mi = methods.TryGetC(type); - if (mi != null) - return Expression.Call(reader, mi, Expression.Constant(ordinal)); - - if (typeof(IBinarySerialize).IsAssignableFrom(type.UnNullify())) - { - if (type.IsNullable()) - return Expression.Call(reader, miGetUdt.MakeGenericMethod(type.UnNullify()), Expression.Constant(ordinal)).Nullify(); - else - return Expression.Call(reader, miGetUdt.MakeGenericMethod(type.UnNullify()), Expression.Constant(ordinal)); - } - - throw new InvalidOperationException("Type {0} not supported".FormatWith(type)); - } - - static MethodInfo miIsNull = ReflectionTools.GetMethodInfo((FieldReader r) => r.IsNull(0)); - - public static Expression GetIsNull(Expression reader, int ordinal) - { - return Expression.Call(reader, miIsNull, Expression.Constant(ordinal)); - } - - internal FieldReaderException CreateFieldReaderException(Exception ex) - { +using System; +using System.Collections.Generic; +using System.Linq; +using Signum.Utilities.Reflection; +using System.Linq.Expressions; +using System.Reflection; +using Signum.Utilities; +using Signum.Engine.Maps; +using Signum.Entities; +using System.Data.SqlTypes; +using System.Data.Common; +//using Microsoft.SqlServer.Types; +using Signum.Utilities.ExpressionTrees; +using System.Data.SqlClient; +using Microsoft.SqlServer.Server; +using System.IO; + +namespace Signum.Engine +{ + public class FieldReader + { + DbDataReader reader; + TypeCode[] typeCodes; + + private const TypeCode tcGuid = (TypeCode)20; + private const TypeCode tcTimeSpan = (TypeCode)21; + private const TypeCode tcDateTimeOffset = (TypeCode)22; + + public int LastOrdinal; + + TypeCode GetTypeCode(int ordinal) + { + Type type = reader.GetFieldType(ordinal); + TypeCode tc = Type.GetTypeCode(type); + if (tc == TypeCode.Object) + { + if (type == typeof(Guid)) + tc = tcGuid; + + if (type == typeof(TimeSpan)) + tc = tcTimeSpan; + + if (type == typeof(DateTimeOffset)) + tc = tcDateTimeOffset; + } + return tc; + } + + public FieldReader(DbDataReader reader) + { + this.reader = reader; + + this.typeCodes = new TypeCode[reader.FieldCount]; + for (int i = 0; i < typeCodes.Length; i++) + typeCodes[i] = GetTypeCode(i); + } + + public bool IsNull(int ordinal) + { + LastOrdinal = ordinal; + return reader.IsDBNull(ordinal); + } + + public string? GetString(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return reader.GetByte(ordinal).ToString(); + case TypeCode.Int16: + return reader.GetInt16(ordinal).ToString(); + case TypeCode.Int32: + return reader.GetInt32(ordinal).ToString(); + case TypeCode.Int64: + return reader.GetInt64(ordinal).ToString(); + case TypeCode.Double: + return reader.GetDouble(ordinal).ToString(); + case TypeCode.Single: + return reader.GetFloat(ordinal).ToString(); + case TypeCode.Decimal: + return reader.GetDecimal(ordinal).ToString(); + case TypeCode.DateTime: + return reader.GetDateTime(ordinal).ToString(); + case tcGuid: + return reader.GetGuid(ordinal).ToString(); + case TypeCode.String: + return reader.GetString(ordinal); + default: + return reader.GetValue(ordinal).ToString(); + } + } + + public byte[]? GetByteArray(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + + return (byte[])reader.GetValue(ordinal); + } + + public bool GetBoolean(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Boolean: + return reader.GetBoolean(ordinal); + case TypeCode.Byte: + return reader.GetByte(ordinal) != 0; + case TypeCode.Int16: + return reader.GetInt16(ordinal) != 0; + case TypeCode.Int32: + return reader.GetInt32(ordinal) != 0; + case TypeCode.Int64: + return reader.GetInt64(ordinal) != 0; + case TypeCode.String: + return bool.Parse(reader.GetString(ordinal)); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public bool? GetNullableBoolean(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetBoolean(ordinal); + } + + + public Byte GetByte(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return reader.GetByte(ordinal); + case TypeCode.Int16: + return (Byte)reader.GetInt16(ordinal); + case TypeCode.Int32: + return (Byte)reader.GetInt32(ordinal); + case TypeCode.Int64: + return (Byte)reader.GetInt64(ordinal); + case TypeCode.Double: + return (Byte)reader.GetDouble(ordinal); + case TypeCode.Single: + return (Byte)reader.GetFloat(ordinal); + case TypeCode.Decimal: + return (Byte)reader.GetDecimal(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Byte? GetNullableByte(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetByte(ordinal); + } + + + public Char GetChar(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return (Char)reader.GetByte(ordinal); + case TypeCode.Int16: + return (Char)reader.GetInt16(ordinal); + case TypeCode.Int32: + return (Char)reader.GetInt32(ordinal); + case TypeCode.Int64: + return (Char)reader.GetInt64(ordinal); + case TypeCode.Double: + return (Char)reader.GetDouble(ordinal); + case TypeCode.Single: + return (Char)reader.GetFloat(ordinal); + case TypeCode.Decimal: + return (Char)reader.GetDecimal(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Char? GetNullableChar(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetChar(ordinal); + } + + + public Single GetFloat(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return (Single)reader.GetByte(ordinal); + case TypeCode.Int16: + return (Single)reader.GetInt16(ordinal); + case TypeCode.Int32: + return (Single)reader.GetInt32(ordinal); + case TypeCode.Int64: + return (Single)reader.GetInt64(ordinal); + case TypeCode.Double: + return (Single)reader.GetDouble(ordinal); + case TypeCode.Single: + return reader.GetFloat(ordinal); + case TypeCode.Decimal: + return (Single)reader.GetDecimal(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Single? GetNullableFloat(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetFloat(ordinal); + } + + + public Double GetDouble(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return (Double)reader.GetByte(ordinal); + case TypeCode.Int16: + return (Double)reader.GetInt16(ordinal); + case TypeCode.Int32: + return (Double)reader.GetInt32(ordinal); + case TypeCode.Int64: + return (Double)reader.GetInt64(ordinal); + case TypeCode.Double: + return reader.GetDouble(ordinal); + case TypeCode.Single: + return (Double)reader.GetFloat(ordinal); + case TypeCode.Decimal: + return (Double)reader.GetDecimal(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Double? GetNullableDouble(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetDouble(ordinal); + } + + + public Decimal GetDecimal(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return (Decimal)reader.GetByte(ordinal); + case TypeCode.Int16: + return (Decimal)reader.GetInt16(ordinal); + case TypeCode.Int32: + return (Decimal)reader.GetInt32(ordinal); + case TypeCode.Int64: + return (Decimal)reader.GetInt64(ordinal); + case TypeCode.Double: + return (Decimal)reader.GetDouble(ordinal); + case TypeCode.Single: + return (Decimal)reader.GetFloat(ordinal); + case TypeCode.Decimal: + return reader.GetDecimal(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Decimal? GetNullableDecimal(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetDecimal(ordinal); + } + + + public Int16 GetInt16(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return (Int16)reader.GetByte(ordinal); + case TypeCode.Int16: + return reader.GetInt16(ordinal); + case TypeCode.Int32: + return (Int16)reader.GetInt32(ordinal); + case TypeCode.Int64: + return (Int16)reader.GetInt64(ordinal); + case TypeCode.Double: + return (Int16)reader.GetDouble(ordinal); + case TypeCode.Single: + return (Int16)reader.GetFloat(ordinal); + case TypeCode.Decimal: + return (Int16)reader.GetDecimal(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Int16? GetNullableInt16(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetInt16(ordinal); + } + + + public Int32 GetInt32(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return (Int32)reader.GetByte(ordinal); + case TypeCode.Int16: + return (Int32)reader.GetInt16(ordinal); + case TypeCode.Int32: + return reader.GetInt32(ordinal); + case TypeCode.Int64: + return (Int32)reader.GetInt64(ordinal); + case TypeCode.Double: + return (Int32)reader.GetDouble(ordinal); + case TypeCode.Single: + return (Int32)reader.GetFloat(ordinal); + case TypeCode.Decimal: + return (Int32)reader.GetDecimal(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Int32? GetNullableInt32(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetInt32(ordinal); + } + + + public Int64 GetInt64(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case TypeCode.Byte: + return (Int64)reader.GetByte(ordinal); + case TypeCode.Int16: + return (Int64)reader.GetInt16(ordinal); + case TypeCode.Int32: + return (Int64)reader.GetInt32(ordinal); + case TypeCode.Int64: + return (Int64)reader.GetInt64(ordinal); + case TypeCode.Double: + return (Int64)reader.GetDouble(ordinal); + case TypeCode.Single: + return (Int64)reader.GetFloat(ordinal); + case TypeCode.Decimal: + return (Int64)reader.GetDecimal(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Int64? GetNullableInt64(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetInt64(ordinal); + } + + + public DateTime GetDateTime(int ordinal) + { + LastOrdinal = ordinal; + DateTime dt; + switch (typeCodes[ordinal]) + { + case TypeCode.DateTime: + dt = reader.GetDateTime(ordinal); + break; + default: + dt = ReflectionTools.ChangeType(reader.GetValue(ordinal)); + break; + } + + if (Schema.Current.TimeZoneMode == TimeZoneMode.Utc) + return new DateTime(dt.Ticks, DateTimeKind.Utc); + + return new DateTime(dt.Ticks, DateTimeKind.Local); + } + + public DateTime? GetNullableDateTime(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetDateTime(ordinal); + } + + + public DateTimeOffset GetDateTimeOffset(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case tcDateTimeOffset: + return ((SqlDataReader)reader).GetDateTimeOffset(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public DateTimeOffset? GetNullableDateTimeOffset(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetDateTimeOffset(ordinal); + } + + + public TimeSpan GetTimeSpan(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case tcTimeSpan: + return ((SqlDataReader)reader).GetTimeSpan(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public TimeSpan? GetNullableTimeSpan(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetTimeSpan(ordinal); + } + + + public Guid GetGuid(int ordinal) + { + LastOrdinal = ordinal; + switch (typeCodes[ordinal]) + { + case tcGuid: + return reader.GetGuid(ordinal); + default: + return ReflectionTools.ChangeType(reader.GetValue(ordinal)); + } + } + + public Guid? GetNullableGuid(int ordinal) + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return null; + } + return GetGuid(ordinal); + } + + static MethodInfo miGetUdt = ReflectionTools.GetMethodInfo((FieldReader r) => r.GetUdt(0)).GetGenericMethodDefinition(); + + public T GetUdt(int ordinal) + where T : IBinarySerialize + { + LastOrdinal = ordinal; + if (reader.IsDBNull(ordinal)) + { + return (T)(object)null!; + } + + var udt = Activator.CreateInstance(); + udt.Read(new BinaryReader(reader.GetStream(ordinal))); + return udt; + } + + static Dictionary methods = + typeof(FieldReader).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) + .Where(m => m.Name != "GetExpression" && m.Name != "IsNull") + .ToDictionary(a => a.ReturnType); + + + public static Expression GetExpression(Expression reader, int ordinal, Type type) + { + MethodInfo? mi = methods.TryGetC(type); + if (mi != null) + return Expression.Call(reader, mi, Expression.Constant(ordinal)); + + if (typeof(IBinarySerialize).IsAssignableFrom(type.UnNullify())) + { + if (type.IsNullable()) + return Expression.Call(reader, miGetUdt.MakeGenericMethod(type.UnNullify()), Expression.Constant(ordinal)).Nullify(); + else + return Expression.Call(reader, miGetUdt.MakeGenericMethod(type.UnNullify()), Expression.Constant(ordinal)); + } + + throw new InvalidOperationException("Type {0} not supported".FormatWith(type)); + } + + static MethodInfo miIsNull = ReflectionTools.GetMethodInfo((FieldReader r) => r.IsNull(0)); + + public static Expression GetIsNull(Expression reader, int ordinal) + { + return Expression.Call(reader, miIsNull, Expression.Constant(ordinal)); + } + + internal FieldReaderException CreateFieldReaderException(Exception ex) + { return new FieldReaderException(ex, ordinal: LastOrdinal, - columnName: reader.GetName(LastOrdinal), - columnType: reader.GetFieldType(LastOrdinal) - ); - } - } - - [Serializable] - public class FieldReaderException : SqlTypeException - { + columnName: reader.GetName(LastOrdinal), + columnType: reader.GetFieldType(LastOrdinal) + ); + } + } + + [Serializable] + public class FieldReaderException : SqlTypeException + { public FieldReaderException(Exception inner, int ordinal, string columnName, Type columnType) : base(null, inner) { this.Ordinal = ordinal; @@ -586,35 +587,35 @@ public FieldReaderException(Exception inner, int ordinal, string columnName, Typ #pragma warning disable CS8618 // Non-nullable field is uninitialized. protected FieldReaderException( #pragma warning restore CS8618 // Non-nullable field is uninitialized. - System.Runtime.Serialization.SerializationInfo info, - System.Runtime.Serialization.StreamingContext context) - : base(info, context) { } - - public override string Message - { - get - { - string text = "{0}\r\nOrdinal: {1}\r\nColumnName: {2}\r\nRow: {3}".FormatWith( - InnerException.Message, Ordinal, ColumnName, Row); - - if (Projector != null) - { - text += "\r\nCalling: row.Reader.Get{0}({1})".FormatWith(ColumnType.Name, Ordinal); - text += "\r\nProjector:\r\n{0}".FormatWith(Projector.ToString().Indent(4)); - } - - if(Command != null) - text += "\r\nCommand:\r\n{0}".FormatWith(Command.PlainSql().Indent(4)); - - return text; - } - } - - public int Ordinal { get; internal set; } - public string ColumnName { get; internal set; } - public Type ColumnType { get; internal set; } - public int Row { get; internal set; } - public SqlPreCommand? Command { get; internal set; } - public LambdaExpression? Projector { get; internal set; } - } -} + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base(info, context) { } + + public override string Message + { + get + { + string text = "{0}\r\nOrdinal: {1}\r\nColumnName: {2}\r\nRow: {3}".FormatWith( + InnerException.Message, Ordinal, ColumnName, Row); + + if (Projector != null) + { + text += "\r\nCalling: row.Reader.Get{0}({1})".FormatWith(ColumnType.Name, Ordinal); + text += "\r\nProjector:\r\n{0}".FormatWith(Projector.ToString().Indent(4)); + } + + if(Command != null) + text += "\r\nCommand:\r\n{0}".FormatWith(Command.PlainSql().Indent(4)); + + return text; + } + } + + public int Ordinal { get; internal set; } + public string ColumnName { get; internal set; } + public Type ColumnType { get; internal set; } + public int Row { get; internal set; } + public SqlPreCommand? Command { get; internal set; } + public LambdaExpression? Projector { get; internal set; } + } +} diff --git a/Signum.React/Scripts/Lines/ValueLine.tsx b/Signum.React/Scripts/Lines/ValueLine.tsx index d8732e372e..a6e088e5b3 100644 --- a/Signum.React/Scripts/Lines/ValueLine.tsx +++ b/Signum.React/Scripts/Lines/ValueLine.tsx @@ -548,7 +548,7 @@ ValueLine.renderers["DateTime" as ValueLineType] = (vl) => { const momentFormat = toMomentFormat(s.formatText); - const m = s.ctx.value ? moment(s.ctx.value, moment.ISO_8601) : undefined; + const m = s.ctx.value ? moment(s.ctx.value) : undefined; const showTime = momentFormat != "L" && momentFormat != "LL"; if (s.ctx.readOnly) diff --git a/Signum.React/Scripts/Reflection.ts b/Signum.React/Scripts/Reflection.ts index f14df6642b..8519e50644 100644 --- a/Signum.React/Scripts/Reflection.ts +++ b/Signum.React/Scripts/Reflection.ts @@ -172,7 +172,7 @@ export function dateToString(val: any, format?: string) { if (val == null) return ""; - var m = moment(val, moment.ISO_8601); + var m = moment(val); return m.format(toMomentFormat(format)); } diff --git a/Signum.React/Scripts/SearchControl/SystemTimeEditor.tsx b/Signum.React/Scripts/SearchControl/SystemTimeEditor.tsx index 70f776430e..6336ab43b4 100644 --- a/Signum.React/Scripts/SearchControl/SystemTimeEditor.tsx +++ b/Signum.React/Scripts/SearchControl/SystemTimeEditor.tsx @@ -140,7 +140,7 @@ export default class SystemTimeEditor extends React.Component From a934de655846c89f852abfb6dd9106f4bcd43ebe Mon Sep 17 00:00:00 2001 From: karimpour Date: Sat, 17 Aug 2019 09:53:34 +0430 Subject: [PATCH 03/46] add createOnFind --- Signum.React/Scripts/Lines/EntityBase.tsx | 5 +++-- Signum.React/Scripts/Lines/EntityListBase.tsx | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Signum.React/Scripts/Lines/EntityBase.tsx b/Signum.React/Scripts/Lines/EntityBase.tsx index fbf365a887..0559096f0c 100644 --- a/Signum.React/Scripts/Lines/EntityBase.tsx +++ b/Signum.React/Scripts/Lines/EntityBase.tsx @@ -19,6 +19,7 @@ export interface EntityBaseProps extends LineBaseProps { viewOnCreate?: boolean; navigate?: boolean; create?: boolean; + createOnFind?: boolean; find?: boolean; remove?: boolean | ((item: any /*T*/) => boolean); @@ -272,12 +273,12 @@ export abstract class EntityBase | undefined> { if (this.state.findOptions) { - return Finder.find(this.state.findOptions); + return Finder.find(this.state.findOptions, { searchControlProps: { create: this.props.createOnFind } }); } return this.chooseType(ti => Finder.isFindable(ti, false)) .then | undefined>(qn => - qn == undefined ? undefined : Finder.find({ queryName: qn } as FindOptions)); + qn == undefined ? undefined : Finder.find({ queryName: qn } as FindOptions, { searchControlProps: { create: this.props.createOnFind } })); } handleFindClick = (event: React.SyntheticEvent) => { diff --git a/Signum.React/Scripts/Lines/EntityListBase.tsx b/Signum.React/Scripts/Lines/EntityListBase.tsx index 37260b840b..07c6d946aa 100644 --- a/Signum.React/Scripts/Lines/EntityListBase.tsx +++ b/Signum.React/Scripts/Lines/EntityListBase.tsx @@ -127,11 +127,12 @@ export abstract class EntityListBase)[] | undefined> { if (this.state.findOptions) { - return Finder.findMany(this.state.findOptions); + return Finder.findMany(this.state.findOptions, { searchControlProps: { create: this.props.createOnFind } }); } return this.chooseType(ti => Finder.isFindable(ti, false)) - .then<(ModifiableEntity | Lite)[] | undefined>(qn => qn == undefined ? undefined : Finder.findMany({ queryName: qn } as FindOptions)); + .then<(ModifiableEntity | Lite)[] | undefined>(qn => qn == undefined ? undefined : + Finder.findMany({ queryName: qn } as FindOptions, { searchControlProps: { create: this.props.createOnFind } })); } addElement(entityOrLite: Lite | ModifiableEntity) { From 44188236a23724733cb461979511178ff5a741d5 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Mon, 19 Aug 2019 09:51:00 +0200 Subject: [PATCH 04/46] add IDiacriticsRemover --- Signum.Utilities/Extensions/StringExtensions.cs | 5 +++++ Signum.Utilities/NaturalLanguage/German.cs | 13 +++++++++++++ .../NaturalLanguage/NaturalLanguageTools.cs | 10 ++++++++++ 3 files changed, 28 insertions(+) diff --git a/Signum.Utilities/Extensions/StringExtensions.cs b/Signum.Utilities/Extensions/StringExtensions.cs index 8667b80b11..9e20698664 100644 --- a/Signum.Utilities/Extensions/StringExtensions.cs +++ b/Signum.Utilities/Extensions/StringExtensions.cs @@ -743,6 +743,11 @@ public static string RemoveDiacritics(this string s) if (string.IsNullOrEmpty(s)) return s; + var dr = NaturalLanguageTools.DiacriticsRemover.TryGetC(CultureInfo.CurrentCulture.TwoLetterISOLanguageName); + + if (dr != null) + s = dr.RemoveDiacritics(s); + string normalizedString = s.Normalize(NormalizationForm.FormD); StringBuilder stringBuilder = new StringBuilder(); diff --git a/Signum.Utilities/NaturalLanguage/German.cs b/Signum.Utilities/NaturalLanguage/German.cs index c67ea0eecd..a4eda2a31d 100644 --- a/Signum.Utilities/NaturalLanguage/German.cs +++ b/Signum.Utilities/NaturalLanguage/German.cs @@ -302,4 +302,17 @@ private static string GetUpToHundred(int number) } + public class GermanDiacriticsRemover : IDiacriticsRemover + { + public string RemoveDiacritics(string str) + { + return str + .Replace("ü", "ue") + .Replace("ä", "ae") + .Replace("ö", "oe") + .Replace("Ü", "Ue") + .Replace("Ä", "Ae") + .Replace("Ö", "Oe"); + } + } } diff --git a/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs b/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs index 22f8d96bf3..cbaf3dcec8 100644 --- a/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs +++ b/Signum.Utilities/NaturalLanguage/NaturalLanguageTools.cs @@ -29,6 +29,11 @@ public static class NaturalLanguageTools {"de", new GermanNumberWriter()}, }; + public static Dictionary DiacriticsRemover = new Dictionary + { + {"de", new GermanDiacriticsRemover()}, + }; + public static char? GetGender(string name, CultureInfo? culture = null) { var defCulture = culture ?? CultureInfo.CurrentUICulture; @@ -287,6 +292,11 @@ public interface INumberWriter string ToNumber(decimal number, NumberWriterSettings settings); } + public interface IDiacriticsRemover + { + string RemoveDiacritics(string str); + } + #pragma warning disable CS8618 // Non-nullable field is uninitialized. public class NumberWriterSettings { From c54c76bcf9b8a079e1a40919cc45c400655dcaaf Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Tue, 20 Aug 2019 16:15:50 +0200 Subject: [PATCH 05/46] add help text to ValueLine inlineCheckbox --- Signum.React/Scripts/Lines/ValueLine.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/Signum.React/Scripts/Lines/ValueLine.tsx b/Signum.React/Scripts/Lines/ValueLine.tsx index 9f99277e86..a79270eca1 100644 --- a/Signum.React/Scripts/Lines/ValueLine.tsx +++ b/Signum.React/Scripts/Lines/ValueLine.tsx @@ -193,6 +193,7 @@ ValueLine.renderers["Checkbox" as ValueLineType] = (vl) => { ); } From 33611910207091ac2d919b799d00a7f9f84af267 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Tue, 20 Aug 2019 16:16:12 +0200 Subject: [PATCH 06/46] add empty collection to IsSetOnlyWhen --- Signum.Entities/ValidationAttributes.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Signum.Entities/ValidationAttributes.cs b/Signum.Entities/ValidationAttributes.cs index 86eb5e2550..bbca206698 100644 --- a/Signum.Entities/ValidationAttributes.cs +++ b/Signum.Entities/ValidationAttributes.cs @@ -92,7 +92,9 @@ public static class NotNullValidatorExtensions { public static string? IsSetOnlyWhen(this (PropertyInfo pi, object? nullableValue) tuple, bool shouldBeSet) { - var isNull = tuple.nullableValue == null || tuple.nullableValue is string s && string.IsNullOrEmpty(s); + var isNull = tuple.nullableValue == null || + tuple.nullableValue is string s && string.IsNullOrEmpty(s) || + tuple.nullableValue is ICollection col && col.Count == 0; if (isNull && shouldBeSet) return ValidationMessage._0IsNotSet.NiceToString(tuple.pi.NiceName()); From 0eb34e9b5166ed365ed3a717b089e6cabc6a44c8 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Wed, 21 Aug 2019 12:09:34 +0200 Subject: [PATCH 07/46] add Navigator.isReadonly(ignoreTypeIsReadonly) to avoid need for showOnReadOnly on System entities --- Signum.React/Scripts/Navigator.tsx | 5 ++--- Signum.React/Scripts/Operations/ContextualOperations.tsx | 4 ++-- Signum.React/Scripts/Operations/EntityOperations.tsx | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Signum.React/Scripts/Navigator.tsx b/Signum.React/Scripts/Navigator.tsx index 7c0112cd02..0d5c9aad25 100644 --- a/Signum.React/Scripts/Navigator.tsx +++ b/Signum.React/Scripts/Navigator.tsx @@ -345,18 +345,17 @@ function typeIsCreable(typeName: string): EntityWhen { export const isReadonlyEvent: Array<(typeName: string, entity?: EntityPack) => boolean> = []; -export function isReadOnly(typeOrEntity: PseudoType | EntityPack) { +export function isReadOnly(typeOrEntity: PseudoType | EntityPack, ignoreTypeIsReadonly: boolean = false) { const entityPack = isEntityPack(typeOrEntity) ? typeOrEntity : undefined; const typeName = isEntityPack(typeOrEntity) ? typeOrEntity.entity.Type : getTypeName(typeOrEntity as PseudoType); - const baseIsReadOnly = typeIsReadOnly(typeName); + const baseIsReadOnly = ignoreTypeIsReadonly ? false : typeIsReadOnly(typeName); return baseIsReadOnly || isReadonlyEvent.some(f => f(typeName, entityPack)); } - function typeIsReadOnly(typeName: string): boolean { const es = entitySettings[typeName]; diff --git a/Signum.React/Scripts/Operations/ContextualOperations.tsx b/Signum.React/Scripts/Operations/ContextualOperations.tsx index d47b4d9abe..7403c7837b 100644 --- a/Signum.React/Scripts/Operations/ContextualOperations.tsx +++ b/Signum.React/Scripts/Operations/ContextualOperations.tsx @@ -114,7 +114,7 @@ export function getEntityOperationsContextualItems(ctx: ContextualItemsContext { contexts.forEach(coc => { coc.canExecute = ep.canExecute[coc.operationInfo.key]; - coc.isReadonly = Navigator.isReadOnly(ep); + coc.isReadonly = Navigator.isReadOnly(ep, true); }); return contexts; }); @@ -130,7 +130,7 @@ export function getEntityOperationsContextualItems(ctx: ContextualItemsContext a.isReadonly = true); } diff --git a/Signum.React/Scripts/Operations/EntityOperations.tsx b/Signum.React/Scripts/Operations/EntityOperations.tsx index d6ff541be0..10b60fa238 100644 --- a/Signum.React/Scripts/Operations/EntityOperations.tsx +++ b/Signum.React/Scripts/Operations/EntityOperations.tsx @@ -53,7 +53,7 @@ export function getEntityOperationButtons(ctx: ButtonsContext): Array Date: Wed, 21 Aug 2019 12:09:48 +0200 Subject: [PATCH 08/46] fix getMember --- Signum.React/Scripts/Reflection.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Signum.React/Scripts/Reflection.ts b/Signum.React/Scripts/Reflection.ts index f14df6642b..dbf54ded2c 100644 --- a/Signum.React/Scripts/Reflection.ts +++ b/Signum.React/Scripts/Reflection.ts @@ -1189,6 +1189,9 @@ let missingSymbols: ISymbol[] = []; function getMember(key: string): MemberInfo | undefined { + if (!key.contains(".")) + return undefined; + const type = _types[key.before(".").toLowerCase()]; if (!type) @@ -1201,9 +1204,14 @@ function getMember(key: string): MemberInfo | undefined { export function symbolNiceName(symbol: Entity & ISymbol | Lite) { if ((symbol as Entity).Type != null) //Don't use isEntity to avoid cycle - return getMember((symbol as Entity & ISymbol).key)!.niceName; - else - return getMember(symbol.toStr!)!.niceName; + { + var m = getMember((symbol as Entity & ISymbol).key); + return m && m.niceName || symbol.toStr; + } + else { + var m = getMember(symbol.toStr!); + return m && m.niceName || symbol.toStr; + } } export function getSymbol(type: Type, key: string) { //Unsafe Type! From 66e45eb6124debaefa9db3db5ec61baf45daf631 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Wed, 21 Aug 2019 16:08:07 +0200 Subject: [PATCH 09/46] make symbolNiceName return string --- Signum.React/Scripts/Reflection.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Signum.React/Scripts/Reflection.ts b/Signum.React/Scripts/Reflection.ts index 77365a57f1..ce860ee718 100644 --- a/Signum.React/Scripts/Reflection.ts +++ b/Signum.React/Scripts/Reflection.ts @@ -1202,15 +1202,15 @@ function getMember(key: string): MemberInfo | undefined { return member; } -export function symbolNiceName(symbol: Entity & ISymbol | Lite) { +export function symbolNiceName(symbol: Entity & ISymbol | Lite) : string { if ((symbol as Entity).Type != null) //Don't use isEntity to avoid cycle { var m = getMember((symbol as Entity & ISymbol).key); - return m && m.niceName || symbol.toStr; + return m && m.niceName || symbol.toStr!; } else { var m = getMember(symbol.toStr!); - return m && m.niceName || symbol.toStr; + return m && m.niceName || symbol.toStr!; } } From ca11d439a03b160726122cb4e85444c5efdbdc3b Mon Sep 17 00:00:00 2001 From: "Hinrichs, Jonas" Date: Wed, 21 Aug 2019 16:12:51 +0200 Subject: [PATCH 10/46] readonly shortend --- Signum.React/Scripts/Lines/FormControlReadonly.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Signum.React/Scripts/Lines/FormControlReadonly.tsx b/Signum.React/Scripts/Lines/FormControlReadonly.tsx index d3bd52632b..fef8ada37a 100644 --- a/Signum.React/Scripts/Lines/FormControlReadonly.tsx +++ b/Signum.React/Scripts/Lines/FormControlReadonly.tsx @@ -22,11 +22,11 @@ export class FormControlReadonly extends React.Component + ); } else { return ( - + ); } } @@ -39,7 +39,7 @@ export class FormControlReadonly extends React.Component +
{this.props.children ||  }
); From 6dc2af99f8525b785269a6c638962205df0145cc Mon Sep 17 00:00:00 2001 From: "Hinrichs, Jonas" Date: Thu, 22 Aug 2019 16:32:42 +0200 Subject: [PATCH 11/46] updateData rename to setData --- Signum.React/Scripts/Hooks.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Signum.React/Scripts/Hooks.ts b/Signum.React/Scripts/Hooks.ts index a683625e85..de7df6fd73 100644 --- a/Signum.React/Scripts/Hooks.ts +++ b/Signum.React/Scripts/Hooks.ts @@ -17,16 +17,16 @@ interface APIHookOptions{ export function useAPI(defaultValue: T, key: ReadonlyArray | undefined, makeCall: (signal: AbortSignal) => Promise, options?: APIHookOptions): T { - const [data, updateData] = React.useState(defaultValue) + const [data, setData] = React.useState(defaultValue); React.useEffect(() => { var abortController = new AbortController(); if (options == null || !options.avoidReset) - updateData(defaultValue); + setData(defaultValue); makeCall(abortController.signal) - .then(result => !abortController.signal.aborted && updateData(result)) + .then(result => !abortController.signal.aborted && setData(result)) .done(); return () => { From 28323c1909ca5ddb6627ae25d76361963776995f Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Thu, 22 Aug 2019 17:16:33 +0200 Subject: [PATCH 12/46] fix GetParentEntity constraint to IModifiableEntity --- Signum.Entities/ModifiableEntity.cs | 8 ++++---- Signum.React/Scripts/SearchControl/SearchControl.tsx | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Signum.Entities/ModifiableEntity.cs b/Signum.Entities/ModifiableEntity.cs index e0cd051027..d1df1603ec 100644 --- a/Signum.Entities/ModifiableEntity.cs +++ b/Signum.Entities/ModifiableEntity.cs @@ -217,18 +217,18 @@ protected virtual void ChildPropertyChanged(object sender, PropertyChangedEventA ModifiableEntity? parentEntity; public T? TryGetParentEntity() - where T: ModifiableEntity + where T: class, IModifiableEntity { - return parentEntity as T; + return ((IModifiableEntity?)parentEntity) as T; } public T GetParentEntity() - where T : ModifiableEntity + where T : IModifiableEntity { if (parentEntity == null) throw new InvalidOperationException("parentEntity is null"); - return (T)parentEntity; + return (T)(IModifiableEntity)parentEntity; } private void SetParentEntity(ModifiableEntity? p) diff --git a/Signum.React/Scripts/SearchControl/SearchControl.tsx b/Signum.React/Scripts/SearchControl/SearchControl.tsx index 9151b5d043..1055f84920 100644 --- a/Signum.React/Scripts/SearchControl/SearchControl.tsx +++ b/Signum.React/Scripts/SearchControl/SearchControl.tsx @@ -51,7 +51,7 @@ export interface SearchControlProps extends React.Props { simpleFilterBuilder?: (sfbc: Finder.SimpleFilterBuilderContext) => React.ReactElement | undefined; onNavigated?: (lite: Lite) => void; onDoubleClick?: (e: React.MouseEvent, row: ResultRow) => void; - onSelectionChanged?: (entity: ResultRow[]) => void; + onSelectionChanged?: (rows: ResultRow[]) => void; onFiltersChanged?: (filters: FilterOptionParsed[]) => void; onHeighChanged?: () => void; onSearch?: (fo: FindOptionsParsed, dataChange: boolean) => void; From d4260d1afb3346cdc727b9a4d3edaf56fb270b35 Mon Sep 17 00:00:00 2001 From: karimpour Date: Sun, 25 Aug 2019 10:13:52 +0430 Subject: [PATCH 13/46] show StackTrace link by ExceptionEntity type rules --- Signum.React/Scripts/Modals/ErrorModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Signum.React/Scripts/Modals/ErrorModal.tsx b/Signum.React/Scripts/Modals/ErrorModal.tsx index 5e9829de5c..e3cfbea5c9 100644 --- a/Signum.React/Scripts/Modals/ErrorModal.tsx +++ b/Signum.React/Scripts/Modals/ErrorModal.tsx @@ -63,7 +63,7 @@ export default class ErrorModal extends React.Component StackTrace {this.state.showDetails &&
{se.httpError.stackTrace}
} From e6d2caded70de5796ff27fd37a935ce4c71f0c8a Mon Sep 17 00:00:00 2001 From: karimpour Date: Mon, 26 Aug 2019 09:43:14 +0430 Subject: [PATCH 14/46] fix getDefaultFilter --- Signum.React/Scripts/Finder.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Signum.React/Scripts/Finder.tsx b/Signum.React/Scripts/Finder.tsx index f9e63781cf..958927e4c8 100644 --- a/Signum.React/Scripts/Finder.tsx +++ b/Signum.React/Scripts/Finder.tsx @@ -500,14 +500,14 @@ export function getDefaultOrder(qd: QueryDescription, qs: QuerySettings | undefi } as OrderOption; } -export function getDefaultFilter(qd: QueryDescription, qs: QuerySettings | undefined): FilterOption[] | undefined { +export function getDefaultFilter(qd: QueryDescription | undefined, qs: QuerySettings | undefined): FilterOption[] | undefined { if (qs && qs.simpleFilterBuilder) return undefined; if (qs && qs.defaultFilters) return qs.defaultFilters; - if (qd.columns["Entity"]) { + if (qd == null || qd.columns["Entity"]) { return [ { groupOperation: "Or", From 761dc0b797820ace47cbc9d62eb3873787632cbd Mon Sep 17 00:00:00 2001 From: karimpour Date: Mon, 26 Aug 2019 09:43:30 +0430 Subject: [PATCH 15/46] add As.ReplaceExpression --- .../ExpressionExpanderAttributes.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Signum.Utilities/ExpressionExpanderAttributes.cs b/Signum.Utilities/ExpressionExpanderAttributes.cs index 8d0d56757d..0a325cbf12 100644 --- a/Signum.Utilities/ExpressionExpanderAttributes.cs +++ b/Signum.Utilities/ExpressionExpanderAttributes.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -104,5 +105,32 @@ public static T Expression(Expression> body) { throw new InvalidOperationException("This method is not meant to be called. Missing reference to Signum.MSBuildTask in this assembly?"); } + + + public static void ReplaceExpressionUntyped(MemberInfo methodOrProperty, LambdaExpression newExpression) + { + var attr = methodOrProperty.GetCustomAttribute(); + + if (attr == null) + throw new InvalidOperationException($"The member {methodOrProperty.Name} has not {nameof(ExpressionFieldAttribute)}"); + + var fi = methodOrProperty.DeclaringType.GetField(attr.Name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + + fi.SetValue(null, newExpression); + } + + public static void ReplaceExpression(Expression> methodOrProperty, Expression> newExpression) + { + var body = methodOrProperty.Body; + + if (body is UnaryExpression u && u.NodeType == ExpressionType.Convert) + body = u.Operand; + + var member = body is MemberExpression m ? m.Expression.Type.GetProperty(((PropertyInfo)m.Member).Name) ?? m.Member: + body is MethodCallExpression mc ? mc.Object?.Type.GetMethod(mc.Method.Name, mc.Method.GetParameters().Select(p=> p.ParameterType).ToArray()) ?? mc.Method : + throw new InvalidOperationException($"Unexpected expression of type {body.NodeType}"); + + ReplaceExpressionUntyped(member, newExpression); + } } } From feef5e492810ec0f6326388323677db039bd92b6 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Mon, 26 Aug 2019 18:19:19 +0200 Subject: [PATCH 16/46] change EntitySettings ViewModule (looks like TS can understand it now) --- Signum.React/Scripts/Navigator.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Signum.React/Scripts/Navigator.tsx b/Signum.React/Scripts/Navigator.tsx index 0d5c9aad25..592dba263a 100644 --- a/Signum.React/Scripts/Navigator.tsx +++ b/Signum.React/Scripts/Navigator.tsx @@ -824,7 +824,7 @@ export class EntitySettings { this.viewOverrides.push({ override, viewName }); } - constructor(type: Type | string, getViewModule?: (entity: T) => Promise>, options?: EntitySettingsOptions) { + constructor(type: Type | string, getViewModule?: (entity: T) => Promise>, options?: EntitySettingsOptions) { this.typeName = (type as Type).typeName || type as string; this.getViewPromise = getViewModule && (entity => new ViewPromise(getViewModule(entity))); From 73adce4be4c8568854773109af75cc88a8056305 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Mon, 26 Aug 2019 18:19:37 +0200 Subject: [PATCH 17/46] add FunctionalAdapter.isInstanceOf --- Signum.React/Scripts/Frames/FrameModal.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Signum.React/Scripts/Frames/FrameModal.tsx b/Signum.React/Scripts/Frames/FrameModal.tsx index ac19ce3877..1f4a31232f 100644 --- a/Signum.React/Scripts/Frames/FrameModal.tsx +++ b/Signum.React/Scripts/Frames/FrameModal.tsx @@ -392,4 +392,17 @@ export class FunctionalAdapter extends React.Component { return {element} } } + + static isInstanceOf(component: React.Component | null | undefined, type: React.ComponentType) { + + if (component instanceof type) + return true; + + if (component instanceof FunctionalAdapter) { + var only = React.Children.only(component.props.children); + return React.isValidElement(only) && only.type == type; + } + + return false + } } From e2b49a46b9ee3c710c7f9606a28fbed0ff304871 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Thu, 29 Aug 2019 15:18:53 +0200 Subject: [PATCH 18/46] add useTitle --- Signum.React/Scripts/Hooks.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Signum.React/Scripts/Hooks.ts b/Signum.React/Scripts/Hooks.ts index de7df6fd73..89a9de48da 100644 --- a/Signum.React/Scripts/Hooks.ts +++ b/Signum.React/Scripts/Hooks.ts @@ -15,6 +15,13 @@ interface APIHookOptions{ avoidReset?: boolean; } +export function useTitle(title: string, deps?: readonly any[]) { + React.useEffect(() => { + Navigator.setTitle(title); + return () => Navigator.setTitle(); + }, deps); +} + export function useAPI(defaultValue: T, key: ReadonlyArray | undefined, makeCall: (signal: AbortSignal) => Promise, options?: APIHookOptions): T { const [data, setData] = React.useState(defaultValue); From af77ddfe53750e65e5709e7dcb9f05b2a0989e76 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Mon, 2 Sep 2019 15:44:56 +0200 Subject: [PATCH 19/46] translation to german --- .../Translations/Signum.Entities.de.xml | 70 ++++++++++++++++--- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/Signum.Entities/Translations/Signum.Entities.de.xml b/Signum.Entities/Translations/Signum.Entities.de.xml index f6288a15b7..e3fc483d10 100644 --- a/Signum.Entities/Translations/Signum.Entities.de.xml +++ b/Signum.Entities/Translations/Signum.Entities.de.xml @@ -14,7 +14,12 @@ - + + + + + + @@ -25,6 +30,7 @@ + @@ -87,7 +93,7 @@ - + @@ -114,7 +120,10 @@ - + + + + @@ -141,11 +150,13 @@ + + @@ -181,6 +192,7 @@ + @@ -203,7 +215,6 @@ - @@ -224,7 +235,7 @@ - + @@ -235,6 +246,8 @@ + + @@ -244,6 +257,7 @@ + @@ -280,10 +294,12 @@ + + @@ -298,9 +314,12 @@ + + + @@ -321,21 +340,26 @@ + + + + + @@ -343,22 +367,35 @@ - + + + + + + + + + + + + + + @@ -382,8 +419,16 @@ - - + + + + + + + + + + @@ -395,13 +440,16 @@ + + + @@ -415,6 +463,7 @@ + @@ -433,6 +482,7 @@ + @@ -447,9 +497,11 @@ + + @@ -462,4 +514,4 @@ - + \ No newline at end of file From cb9b967302ac8900459bea4a68c188ddb70bba41 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Mon, 2 Sep 2019 15:45:22 +0200 Subject: [PATCH 20/46] add SelectorMessage.chooseEnum --- Signum.Entities/EnumMessages.cs | 8 ++++++-- Signum.React/Scripts/SelectorModal.tsx | 13 ++++++++++++- Signum.React/Scripts/Signum.Entities.ts | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Signum.Entities/EnumMessages.cs b/Signum.Entities/EnumMessages.cs index 2046e905dc..41f6db6a8c 100644 --- a/Signum.Entities/EnumMessages.cs +++ b/Signum.Entities/EnumMessages.cs @@ -213,7 +213,7 @@ public enum SelectorMessage ConstructorSelector, [Description("Please choose a value to continue:")] PleaseChooseAValueToContinue, - [Description("Please select a Constructor")] + [Description("Please select a constructor")] PleaseSelectAConstructor, [Description("Please select one of the following types: ")] PleaseSelectAType, @@ -223,7 +223,11 @@ public enum SelectorMessage ValueMustBeSpecifiedFor0, ChooseAValue, SelectAnElement, - PleaseSelectAnElement + PleaseSelectAnElement, + [Description("{0} selector")] + _0Selector, + [Description("Please choose a {0} to continue:")] + PleaseChooseA0ToContinue, } public enum ConnectionMessage diff --git a/Signum.React/Scripts/SelectorModal.tsx b/Signum.React/Scripts/SelectorModal.tsx index 5077c7b0b7..ad5dc56d63 100644 --- a/Signum.React/Scripts/SelectorModal.tsx +++ b/Signum.React/Scripts/SelectorModal.tsx @@ -1,7 +1,7 @@ import * as React from 'react' import { openModal, IModalProps } from './Modals'; import { SelectorMessage } from './Signum.Entities' -import { TypeInfo } from './Reflection' +import { TypeInfo, EnumType } from './Reflection' import { Modal, BsSize } from './Components'; interface SelectorModalProps extends React.Props, IModalProps { @@ -86,6 +86,17 @@ export default class SelectorModal extends React.Component); } + static chooseEnum(enumType: EnumType): Promise{ + return SelectorModal.chooseElement(enumType.values(), + { + buttonDisplay: a => enumType.niceToString(a), + buttonName: a => a, + title: SelectorMessage._0Selector.niceToString(enumType.niceTypeName()), + message: SelectorMessage.PleaseChooseA0ToContinue.niceToString(enumType.niceTypeName()), + size: "md", + }); + } + static chooseType(options: TypeInfo[]): Promise { return SelectorModal.chooseElement(options, { diff --git a/Signum.React/Scripts/Signum.Entities.ts b/Signum.React/Scripts/Signum.Entities.ts index 4048c2aac8..2139dbe5f0 100644 --- a/Signum.React/Scripts/Signum.Entities.ts +++ b/Signum.React/Scripts/Signum.Entities.ts @@ -474,6 +474,8 @@ export module SelectorMessage { export const ChooseAValue = new MessageKey("SelectorMessage", "ChooseAValue"); export const SelectAnElement = new MessageKey("SelectorMessage", "SelectAnElement"); export const PleaseSelectAnElement = new MessageKey("SelectorMessage", "PleaseSelectAnElement"); + export const _0Selector = new MessageKey("SelectorMessage", "_0Selector"); + export const PleaseChooseA0ToContinue = new MessageKey("SelectorMessage", "PleaseChooseA0ToContinue"); } export interface Symbol extends Entity { From 8725594ef561846a8307abf3ee0ac952695c0278 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Tue, 3 Sep 2019 17:10:43 +0200 Subject: [PATCH 21/46] add MemComparer to Signum.Utilities --- .../JsonConverters/EntityJsonConverter.cs | 18 +++------------ .../DataStructures/MemComparer.cs | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 Signum.Utilities/DataStructures/MemComparer.cs diff --git a/Signum.React/JsonConverters/EntityJsonConverter.cs b/Signum.React/JsonConverters/EntityJsonConverter.cs index 963b2c7fd7..a421ecc14d 100644 --- a/Signum.React/JsonConverters/EntityJsonConverter.cs +++ b/Signum.React/JsonConverters/EntityJsonConverter.cs @@ -6,6 +6,7 @@ using Signum.Entities.Reflection; using Signum.React.Facades; using Signum.Utilities; +using Signum.Utilities.DataStructures; using Signum.Utilities.ExpressionTrees; using Signum.Utilities.Reflection; using System; @@ -389,7 +390,7 @@ public void ReadJsonProperty(JsonReader reader, JsonSerializer serializer, Modif private bool IsEquals(object newValue, object? oldValue) { if (newValue is byte[] && oldValue is byte[]) - return MemCompare.Compare((byte[])newValue, (byte[])oldValue); + return MemComparer.Equals((byte[])newValue, (byte[])oldValue); if (newValue is DateTime && oldValue is DateTime) return Math.Abs(((DateTime)newValue).Subtract((DateTime)oldValue).TotalMilliseconds) < 10; //Json dates get rounded @@ -531,18 +532,5 @@ static Type GetEntityType(string typeStr, Type objectType) } - static class MemCompare - { - [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] -#pragma warning disable IDE1006 // Naming Styles - static extern int memcmp(byte[] b1, byte[] b2, long count); -#pragma warning restore IDE1006 // Naming Styles - - public static bool Compare(byte[] b1, byte[] b2) - { - // Validate buffers are the same length. - // This also ensures that the count does not exceed the length of either buffer. - return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0; - } - } + } diff --git a/Signum.Utilities/DataStructures/MemComparer.cs b/Signum.Utilities/DataStructures/MemComparer.cs new file mode 100644 index 0000000000..0553fe3ed5 --- /dev/null +++ b/Signum.Utilities/DataStructures/MemComparer.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace Signum.Utilities.DataStructures +{ + public static class MemComparer + { + [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] +#pragma warning disable IDE1006 // Naming Styles + static extern int memcmp(byte[] b1, byte[] b2, long count); +#pragma warning restore IDE1006 // Naming Styles + + public static bool Equals(byte[] b1, byte[] b2) + { + // Validate buffers are the same length. + // This also ensures that the count does not exceed the length of either buffer. + return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0; + } + } +} From 0b0e0cff677a210baa1cfaab3da1546e1428c5f7 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Tue, 3 Sep 2019 17:57:02 +0200 Subject: [PATCH 22/46] pass EntityCombo selectHtmlAttributes in readonly mode --- Signum.React/Scripts/Lines/EntityCombo.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Signum.React/Scripts/Lines/EntityCombo.tsx b/Signum.React/Scripts/Lines/EntityCombo.tsx index 74301b1b0b..ee47fc905e 100644 --- a/Signum.React/Scripts/Lines/EntityCombo.tsx +++ b/Signum.React/Scripts/Lines/EntityCombo.tsx @@ -166,7 +166,7 @@ class EntityComboSelect extends React.Component{ctx.value && getToString(lite, this.props.liteToString)}; + return {ctx.value && getToString(lite, this.props.liteToString)}; return (